<!DOCTYPE html>
<html>
<head><meta charset="utf-8" />
<title>Deep_Learning_Project</title><script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

<style type="text/css">
    /*!
*
* Twitter Bootstrap
*
*/
/*!
 * Bootstrap v3.3.7 (http://getbootstrap.com)
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
  font-family: sans-serif;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
  display: block;
}
audio,
canvas,
progress,
video {
  display: inline-block;
  vertical-align: baseline;
}
audio:not([controls]) {
  display: none;
  height: 0;
}
[hidden],
template {
  display: none;
}
a {
  background-color: transparent;
}
a:active,
a:hover {
  outline: 0;
}
abbr[title] {
  border-bottom: 1px dotted;
}
b,
strong {
  font-weight: bold;
}
dfn {
  font-style: italic;
}
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}
mark {
  background: #ff0;
  color: #000;
}
small {
  font-size: 80%;
}
sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
sup {
  top: -0.5em;
}
sub {
  bottom: -0.25em;
}
img {
  border: 0;
}
svg:not(:root) {
  overflow: hidden;
}
figure {
  margin: 1em 40px;
}
hr {
  box-sizing: content-box;
  height: 0;
}
pre {
  overflow: auto;
}
code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}
button,
input,
optgroup,
select,
textarea {
  color: inherit;
  font: inherit;
  margin: 0;
}
button {
  overflow: visible;
}
button,
select {
  text-transform: none;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button;
  cursor: pointer;
}
button[disabled],
html input[disabled] {
  cursor: default;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
  border: 0;
  padding: 0;
}
input {
  line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
  box-sizing: border-box;
  padding: 0;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}
input[type="search"] {
  -webkit-appearance: textfield;
  box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}
fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}
legend {
  border: 0;
  padding: 0;
}
textarea {
  overflow: auto;
}
optgroup {
  font-weight: bold;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
td,
th {
  padding: 0;
}
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
@media print {
  *,
  *:before,
  *:after {
    background: transparent !important;
    color: #000 !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }
  a,
  a:visited {
    text-decoration: underline;
  }
  a[href]:after {
    content: " (" attr(href) ")";
  }
  abbr[title]:after {
    content: " (" attr(title) ")";
  }
  a[href^="#"]:after,
  a[href^="javascript:"]:after {
    content: "";
  }
  pre,
  blockquote {
    border: 1px solid #999;
    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr,
  img {
    page-break-inside: avoid;
  }
  img {
    max-width: 100% !important;
  }
  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }
  h2,
  h3 {
    page-break-after: avoid;
  }
  .navbar {
    display: none;
  }
  .btn > .caret,
  .dropup > .btn > .caret {
    border-top-color: #000 !important;
  }
  .label {
    border: 1px solid #000;
  }
  .table {
    border-collapse: collapse !important;
  }
  .table td,
  .table th {
    background-color: #fff !important;
  }
  .table-bordered th,
  .table-bordered td {
    border: 1px solid #ddd !important;
  }
}
@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
  src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
  position: relative;
  top: 1px;
  display: inline-block;
  font-family: 'Glyphicons Halflings';
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.glyphicon-asterisk:before {
  content: "\002a";
}
.glyphicon-plus:before {
  content: "\002b";
}
.glyphicon-euro:before,
.glyphicon-eur:before {
  content: "\20ac";
}
.glyphicon-minus:before {
  content: "\2212";
}
.glyphicon-cloud:before {
  content: "\2601";
}
.glyphicon-envelope:before {
  content: "\2709";
}
.glyphicon-pencil:before {
  content: "\270f";
}
.glyphicon-glass:before {
  content: "\e001";
}
.glyphicon-music:before {
  content: "\e002";
}
.glyphicon-search:before {
  content: "\e003";
}
.glyphicon-heart:before {
  content: "\e005";
}
.glyphicon-star:before {
  content: "\e006";
}
.glyphicon-star-empty:before {
  content: "\e007";
}
.glyphicon-user:before {
  content: "\e008";
}
.glyphicon-film:before {
  content: "\e009";
}
.glyphicon-th-large:before {
  content: "\e010";
}
.glyphicon-th:before {
  content: "\e011";
}
.glyphicon-th-list:before {
  content: "\e012";
}
.glyphicon-ok:before {
  content: "\e013";
}
.glyphicon-remove:before {
  content: "\e014";
}
.glyphicon-zoom-in:before {
  content: "\e015";
}
.glyphicon-zoom-out:before {
  content: "\e016";
}
.glyphicon-off:before {
  content: "\e017";
}
.glyphicon-signal:before {
  content: "\e018";
}
.glyphicon-cog:before {
  content: "\e019";
}
.glyphicon-trash:before {
  content: "\e020";
}
.glyphicon-home:before {
  content: "\e021";
}
.glyphicon-file:before {
  content: "\e022";
}
.glyphicon-time:before {
  content: "\e023";
}
.glyphicon-road:before {
  content: "\e024";
}
.glyphicon-download-alt:before {
  content: "\e025";
}
.glyphicon-download:before {
  content: "\e026";
}
.glyphicon-upload:before {
  content: "\e027";
}
.glyphicon-inbox:before {
  content: "\e028";
}
.glyphicon-play-circle:before {
  content: "\e029";
}
.glyphicon-repeat:before {
  content: "\e030";
}
.glyphicon-refresh:before {
  content: "\e031";
}
.glyphicon-list-alt:before {
  content: "\e032";
}
.glyphicon-lock:before {
  content: "\e033";
}
.glyphicon-flag:before {
  content: "\e034";
}
.glyphicon-headphones:before {
  content: "\e035";
}
.glyphicon-volume-off:before {
  content: "\e036";
}
.glyphicon-volume-down:before {
  content: "\e037";
}
.glyphicon-volume-up:before {
  content: "\e038";
}
.glyphicon-qrcode:before {
  content: "\e039";
}
.glyphicon-barcode:before {
  content: "\e040";
}
.glyphicon-tag:before {
  content: "\e041";
}
.glyphicon-tags:before {
  content: "\e042";
}
.glyphicon-book:before {
  content: "\e043";
}
.glyphicon-bookmark:before {
  content: "\e044";
}
.glyphicon-print:before {
  content: "\e045";
}
.glyphicon-camera:before {
  content: "\e046";
}
.glyphicon-font:before {
  content: "\e047";
}
.glyphicon-bold:before {
  content: "\e048";
}
.glyphicon-italic:before {
  content: "\e049";
}
.glyphicon-text-height:before {
  content: "\e050";
}
.glyphicon-text-width:before {
  content: "\e051";
}
.glyphicon-align-left:before {
  content: "\e052";
}
.glyphicon-align-center:before {
  content: "\e053";
}
.glyphicon-align-right:before {
  content: "\e054";
}
.glyphicon-align-justify:before {
  content: "\e055";
}
.glyphicon-list:before {
  content: "\e056";
}
.glyphicon-indent-left:before {
  content: "\e057";
}
.glyphicon-indent-right:before {
  content: "\e058";
}
.glyphicon-facetime-video:before {
  content: "\e059";
}
.glyphicon-picture:before {
  content: "\e060";
}
.glyphicon-map-marker:before {
  content: "\e062";
}
.glyphicon-adjust:before {
  content: "\e063";
}
.glyphicon-tint:before {
  content: "\e064";
}
.glyphicon-edit:before {
  content: "\e065";
}
.glyphicon-share:before {
  content: "\e066";
}
.glyphicon-check:before {
  content: "\e067";
}
.glyphicon-move:before {
  content: "\e068";
}
.glyphicon-step-backward:before {
  content: "\e069";
}
.glyphicon-fast-backward:before {
  content: "\e070";
}
.glyphicon-backward:before {
  content: "\e071";
}
.glyphicon-play:before {
  content: "\e072";
}
.glyphicon-pause:before {
  content: "\e073";
}
.glyphicon-stop:before {
  content: "\e074";
}
.glyphicon-forward:before {
  content: "\e075";
}
.glyphicon-fast-forward:before {
  content: "\e076";
}
.glyphicon-step-forward:before {
  content: "\e077";
}
.glyphicon-eject:before {
  content: "\e078";
}
.glyphicon-chevron-left:before {
  content: "\e079";
}
.glyphicon-chevron-right:before {
  content: "\e080";
}
.glyphicon-plus-sign:before {
  content: "\e081";
}
.glyphicon-minus-sign:before {
  content: "\e082";
}
.glyphicon-remove-sign:before {
  content: "\e083";
}
.glyphicon-ok-sign:before {
  content: "\e084";
}
.glyphicon-question-sign:before {
  content: "\e085";
}
.glyphicon-info-sign:before {
  content: "\e086";
}
.glyphicon-screenshot:before {
  content: "\e087";
}
.glyphicon-remove-circle:before {
  content: "\e088";
}
.glyphicon-ok-circle:before {
  content: "\e089";
}
.glyphicon-ban-circle:before {
  content: "\e090";
}
.glyphicon-arrow-left:before {
  content: "\e091";
}
.glyphicon-arrow-right:before {
  content: "\e092";
}
.glyphicon-arrow-up:before {
  content: "\e093";
}
.glyphicon-arrow-down:before {
  content: "\e094";
}
.glyphicon-share-alt:before {
  content: "\e095";
}
.glyphicon-resize-full:before {
  content: "\e096";
}
.glyphicon-resize-small:before {
  content: "\e097";
}
.glyphicon-exclamation-sign:before {
  content: "\e101";
}
.glyphicon-gift:before {
  content: "\e102";
}
.glyphicon-leaf:before {
  content: "\e103";
}
.glyphicon-fire:before {
  content: "\e104";
}
.glyphicon-eye-open:before {
  content: "\e105";
}
.glyphicon-eye-close:before {
  content: "\e106";
}
.glyphicon-warning-sign:before {
  content: "\e107";
}
.glyphicon-plane:before {
  content: "\e108";
}
.glyphicon-calendar:before {
  content: "\e109";
}
.glyphicon-random:before {
  content: "\e110";
}
.glyphicon-comment:before {
  content: "\e111";
}
.glyphicon-magnet:before {
  content: "\e112";
}
.glyphicon-chevron-up:before {
  content: "\e113";
}
.glyphicon-chevron-down:before {
  content: "\e114";
}
.glyphicon-retweet:before {
  content: "\e115";
}
.glyphicon-shopping-cart:before {
  content: "\e116";
}
.glyphicon-folder-close:before {
  content: "\e117";
}
.glyphicon-folder-open:before {
  content: "\e118";
}
.glyphicon-resize-vertical:before {
  content: "\e119";
}
.glyphicon-resize-horizontal:before {
  content: "\e120";
}
.glyphicon-hdd:before {
  content: "\e121";
}
.glyphicon-bullhorn:before {
  content: "\e122";
}
.glyphicon-bell:before {
  content: "\e123";
}
.glyphicon-certificate:before {
  content: "\e124";
}
.glyphicon-thumbs-up:before {
  content: "\e125";
}
.glyphicon-thumbs-down:before {
  content: "\e126";
}
.glyphicon-hand-right:before {
  content: "\e127";
}
.glyphicon-hand-left:before {
  content: "\e128";
}
.glyphicon-hand-up:before {
  content: "\e129";
}
.glyphicon-hand-down:before {
  content: "\e130";
}
.glyphicon-circle-arrow-right:before {
  content: "\e131";
}
.glyphicon-circle-arrow-left:before {
  content: "\e132";
}
.glyphicon-circle-arrow-up:before {
  content: "\e133";
}
.glyphicon-circle-arrow-down:before {
  content: "\e134";
}
.glyphicon-globe:before {
  content: "\e135";
}
.glyphicon-wrench:before {
  content: "\e136";
}
.glyphicon-tasks:before {
  content: "\e137";
}
.glyphicon-filter:before {
  content: "\e138";
}
.glyphicon-briefcase:before {
  content: "\e139";
}
.glyphicon-fullscreen:before {
  content: "\e140";
}
.glyphicon-dashboard:before {
  content: "\e141";
}
.glyphicon-paperclip:before {
  content: "\e142";
}
.glyphicon-heart-empty:before {
  content: "\e143";
}
.glyphicon-link:before {
  content: "\e144";
}
.glyphicon-phone:before {
  content: "\e145";
}
.glyphicon-pushpin:before {
  content: "\e146";
}
.glyphicon-usd:before {
  content: "\e148";
}
.glyphicon-gbp:before {
  content: "\e149";
}
.glyphicon-sort:before {
  content: "\e150";
}
.glyphicon-sort-by-alphabet:before {
  content: "\e151";
}
.glyphicon-sort-by-alphabet-alt:before {
  content: "\e152";
}
.glyphicon-sort-by-order:before {
  content: "\e153";
}
.glyphicon-sort-by-order-alt:before {
  content: "\e154";
}
.glyphicon-sort-by-attributes:before {
  content: "\e155";
}
.glyphicon-sort-by-attributes-alt:before {
  content: "\e156";
}
.glyphicon-unchecked:before {
  content: "\e157";
}
.glyphicon-expand:before {
  content: "\e158";
}
.glyphicon-collapse-down:before {
  content: "\e159";
}
.glyphicon-collapse-up:before {
  content: "\e160";
}
.glyphicon-log-in:before {
  content: "\e161";
}
.glyphicon-flash:before {
  content: "\e162";
}
.glyphicon-log-out:before {
  content: "\e163";
}
.glyphicon-new-window:before {
  content: "\e164";
}
.glyphicon-record:before {
  content: "\e165";
}
.glyphicon-save:before {
  content: "\e166";
}
.glyphicon-open:before {
  content: "\e167";
}
.glyphicon-saved:before {
  content: "\e168";
}
.glyphicon-import:before {
  content: "\e169";
}
.glyphicon-export:before {
  content: "\e170";
}
.glyphicon-send:before {
  content: "\e171";
}
.glyphicon-floppy-disk:before {
  content: "\e172";
}
.glyphicon-floppy-saved:before {
  content: "\e173";
}
.glyphicon-floppy-remove:before {
  content: "\e174";
}
.glyphicon-floppy-save:before {
  content: "\e175";
}
.glyphicon-floppy-open:before {
  content: "\e176";
}
.glyphicon-credit-card:before {
  content: "\e177";
}
.glyphicon-transfer:before {
  content: "\e178";
}
.glyphicon-cutlery:before {
  content: "\e179";
}
.glyphicon-header:before {
  content: "\e180";
}
.glyphicon-compressed:before {
  content: "\e181";
}
.glyphicon-earphone:before {
  content: "\e182";
}
.glyphicon-phone-alt:before {
  content: "\e183";
}
.glyphicon-tower:before {
  content: "\e184";
}
.glyphicon-stats:before {
  content: "\e185";
}
.glyphicon-sd-video:before {
  content: "\e186";
}
.glyphicon-hd-video:before {
  content: "\e187";
}
.glyphicon-subtitles:before {
  content: "\e188";
}
.glyphicon-sound-stereo:before {
  content: "\e189";
}
.glyphicon-sound-dolby:before {
  content: "\e190";
}
.glyphicon-sound-5-1:before {
  content: "\e191";
}
.glyphicon-sound-6-1:before {
  content: "\e192";
}
.glyphicon-sound-7-1:before {
  content: "\e193";
}
.glyphicon-copyright-mark:before {
  content: "\e194";
}
.glyphicon-registration-mark:before {
  content: "\e195";
}
.glyphicon-cloud-download:before {
  content: "\e197";
}
.glyphicon-cloud-upload:before {
  content: "\e198";
}
.glyphicon-tree-conifer:before {
  content: "\e199";
}
.glyphicon-tree-deciduous:before {
  content: "\e200";
}
.glyphicon-cd:before {
  content: "\e201";
}
.glyphicon-save-file:before {
  content: "\e202";
}
.glyphicon-open-file:before {
  content: "\e203";
}
.glyphicon-level-up:before {
  content: "\e204";
}
.glyphicon-copy:before {
  content: "\e205";
}
.glyphicon-paste:before {
  content: "\e206";
}
.glyphicon-alert:before {
  content: "\e209";
}
.glyphicon-equalizer:before {
  content: "\e210";
}
.glyphicon-king:before {
  content: "\e211";
}
.glyphicon-queen:before {
  content: "\e212";
}
.glyphicon-pawn:before {
  content: "\e213";
}
.glyphicon-bishop:before {
  content: "\e214";
}
.glyphicon-knight:before {
  content: "\e215";
}
.glyphicon-baby-formula:before {
  content: "\e216";
}
.glyphicon-tent:before {
  content: "\26fa";
}
.glyphicon-blackboard:before {
  content: "\e218";
}
.glyphicon-bed:before {
  content: "\e219";
}
.glyphicon-apple:before {
  content: "\f8ff";
}
.glyphicon-erase:before {
  content: "\e221";
}
.glyphicon-hourglass:before {
  content: "\231b";
}
.glyphicon-lamp:before {
  content: "\e223";
}
.glyphicon-duplicate:before {
  content: "\e224";
}
.glyphicon-piggy-bank:before {
  content: "\e225";
}
.glyphicon-scissors:before {
  content: "\e226";
}
.glyphicon-bitcoin:before {
  content: "\e227";
}
.glyphicon-btc:before {
  content: "\e227";
}
.glyphicon-xbt:before {
  content: "\e227";
}
.glyphicon-yen:before {
  content: "\00a5";
}
.glyphicon-jpy:before {
  content: "\00a5";
}
.glyphicon-ruble:before {
  content: "\20bd";
}
.glyphicon-rub:before {
  content: "\20bd";
}
.glyphicon-scale:before {
  content: "\e230";
}
.glyphicon-ice-lolly:before {
  content: "\e231";
}
.glyphicon-ice-lolly-tasted:before {
  content: "\e232";
}
.glyphicon-education:before {
  content: "\e233";
}
.glyphicon-option-horizontal:before {
  content: "\e234";
}
.glyphicon-option-vertical:before {
  content: "\e235";
}
.glyphicon-menu-hamburger:before {
  content: "\e236";
}
.glyphicon-modal-window:before {
  content: "\e237";
}
.glyphicon-oil:before {
  content: "\e238";
}
.glyphicon-grain:before {
  content: "\e239";
}
.glyphicon-sunglasses:before {
  content: "\e240";
}
.glyphicon-text-size:before {
  content: "\e241";
}
.glyphicon-text-color:before {
  content: "\e242";
}
.glyphicon-text-background:before {
  content: "\e243";
}
.glyphicon-object-align-top:before {
  content: "\e244";
}
.glyphicon-object-align-bottom:before {
  content: "\e245";
}
.glyphicon-object-align-horizontal:before {
  content: "\e246";
}
.glyphicon-object-align-left:before {
  content: "\e247";
}
.glyphicon-object-align-vertical:before {
  content: "\e248";
}
.glyphicon-object-align-right:before {
  content: "\e249";
}
.glyphicon-triangle-right:before {
  content: "\e250";
}
.glyphicon-triangle-left:before {
  content: "\e251";
}
.glyphicon-triangle-bottom:before {
  content: "\e252";
}
.glyphicon-triangle-top:before {
  content: "\e253";
}
.glyphicon-console:before {
  content: "\e254";
}
.glyphicon-superscript:before {
  content: "\e255";
}
.glyphicon-subscript:before {
  content: "\e256";
}
.glyphicon-menu-left:before {
  content: "\e257";
}
.glyphicon-menu-right:before {
  content: "\e258";
}
.glyphicon-menu-down:before {
  content: "\e259";
}
.glyphicon-menu-up:before {
  content: "\e260";
}
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
*:before,
*:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html {
  font-size: 10px;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  line-height: 1.42857143;
  color: #000;
  background-color: #fff;
}
input,
button,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}
a {
  color: #337ab7;
  text-decoration: none;
}
a:hover,
a:focus {
  color: #23527c;
  text-decoration: underline;
}
a:focus {
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
figure {
  margin: 0;
}
img {
  vertical-align: middle;
}
.img-responsive,
.thumbnail > img,
.thumbnail a > img,
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
  display: block;
  max-width: 100%;
  height: auto;
}
.img-rounded {
  border-radius: 3px;
}
.img-thumbnail {
  padding: 4px;
  line-height: 1.42857143;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 2px;
  -webkit-transition: all 0.2s ease-in-out;
  -o-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  display: inline-block;
  max-width: 100%;
  height: auto;
}
.img-circle {
  border-radius: 50%;
}
hr {
  margin-top: 18px;
  margin-bottom: 18px;
  border: 0;
  border-top: 1px solid #eeeeee;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
}
[role="button"] {
  cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
  font-family: inherit;
  font-weight: 500;
  line-height: 1.1;
  color: inherit;
}
h1 small,
h2 small,
h3 small,
h4 small,
h5 small,
h6 small,
.h1 small,
.h2 small,
.h3 small,
.h4 small,
.h5 small,
.h6 small,
h1 .small,
h2 .small,
h3 .small,
h4 .small,
h5 .small,
h6 .small,
.h1 .small,
.h2 .small,
.h3 .small,
.h4 .small,
.h5 .small,
.h6 .small {
  font-weight: normal;
  line-height: 1;
  color: #777777;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
  margin-top: 18px;
  margin-bottom: 9px;
}
h1 small,
.h1 small,
h2 small,
.h2 small,
h3 small,
.h3 small,
h1 .small,
.h1 .small,
h2 .small,
.h2 .small,
h3 .small,
.h3 .small {
  font-size: 65%;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
  margin-top: 9px;
  margin-bottom: 9px;
}
h4 small,
.h4 small,
h5 small,
.h5 small,
h6 small,
.h6 small,
h4 .small,
.h4 .small,
h5 .small,
.h5 .small,
h6 .small,
.h6 .small {
  font-size: 75%;
}
h1,
.h1 {
  font-size: 33px;
}
h2,
.h2 {
  font-size: 27px;
}
h3,
.h3 {
  font-size: 23px;
}
h4,
.h4 {
  font-size: 17px;
}
h5,
.h5 {
  font-size: 13px;
}
h6,
.h6 {
  font-size: 12px;
}
p {
  margin: 0 0 9px;
}
.lead {
  margin-bottom: 18px;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.4;
}
@media (min-width: 768px) {
  .lead {
    font-size: 19.5px;
  }
}
small,
.small {
  font-size: 92%;
}
mark,
.mark {
  background-color: #fcf8e3;
  padding: .2em;
}
.text-left {
  text-align: left;
}
.text-right {
  text-align: right;
}
.text-center {
  text-align: center;
}
.text-justify {
  text-align: justify;
}
.text-nowrap {
  white-space: nowrap;
}
.text-lowercase {
  text-transform: lowercase;
}
.text-uppercase {
  text-transform: uppercase;
}
.text-capitalize {
  text-transform: capitalize;
}
.text-muted {
  color: #777777;
}
.text-primary {
  color: #337ab7;
}
a.text-primary:hover,
a.text-primary:focus {
  color: #286090;
}
.text-success {
  color: #3c763d;
}
a.text-success:hover,
a.text-success:focus {
  color: #2b542c;
}
.text-info {
  color: #31708f;
}
a.text-info:hover,
a.text-info:focus {
  color: #245269;
}
.text-warning {
  color: #8a6d3b;
}
a.text-warning:hover,
a.text-warning:focus {
  color: #66512c;
}
.text-danger {
  color: #a94442;
}
a.text-danger:hover,
a.text-danger:focus {
  color: #843534;
}
.bg-primary {
  color: #fff;
  background-color: #337ab7;
}
a.bg-primary:hover,
a.bg-primary:focus {
  background-color: #286090;
}
.bg-success {
  background-color: #dff0d8;
}
a.bg-success:hover,
a.bg-success:focus {
  background-color: #c1e2b3;
}
.bg-info {
  background-color: #d9edf7;
}
a.bg-info:hover,
a.bg-info:focus {
  background-color: #afd9ee;
}
.bg-warning {
  background-color: #fcf8e3;
}
a.bg-warning:hover,
a.bg-warning:focus {
  background-color: #f7ecb5;
}
.bg-danger {
  background-color: #f2dede;
}
a.bg-danger:hover,
a.bg-danger:focus {
  background-color: #e4b9b9;
}
.page-header {
  padding-bottom: 8px;
  margin: 36px 0 18px;
  border-bottom: 1px solid #eeeeee;
}
ul,
ol {
  margin-top: 0;
  margin-bottom: 9px;
}
ul ul,
ol ul,
ul ol,
ol ol {
  margin-bottom: 0;
}
.list-unstyled {
  padding-left: 0;
  list-style: none;
}
.list-inline {
  padding-left: 0;
  list-style: none;
  margin-left: -5px;
}
.list-inline > li {
  display: inline-block;
  padding-left: 5px;
  padding-right: 5px;
}
dl {
  margin-top: 0;
  margin-bottom: 18px;
}
dt,
dd {
  line-height: 1.42857143;
}
dt {
  font-weight: bold;
}
dd {
  margin-left: 0;
}
@media (min-width: 541px) {
  .dl-horizontal dt {
    float: left;
    width: 160px;
    clear: left;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .dl-horizontal dd {
    margin-left: 180px;
  }
}
abbr[title],
abbr[data-original-title] {
  cursor: help;
  border-bottom: 1px dotted #777777;
}
.initialism {
  font-size: 90%;
  text-transform: uppercase;
}
blockquote {
  padding: 9px 18px;
  margin: 0 0 18px;
  font-size: inherit;
  border-left: 5px solid #eeeeee;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
  margin-bottom: 0;
}
blockquote footer,
blockquote small,
blockquote .small {
  display: block;
  font-size: 80%;
  line-height: 1.42857143;
  color: #777777;
}
blockquote footer:before,
blockquote small:before,
blockquote .small:before {
  content: '\2014 \00A0';
}
.blockquote-reverse,
blockquote.pull-right {
  padding-right: 15px;
  padding-left: 0;
  border-right: 5px solid #eeeeee;
  border-left: 0;
  text-align: right;
}
.blockquote-reverse footer:before,
blockquote.pull-right footer:before,
.blockquote-reverse small:before,
blockquote.pull-right small:before,
.blockquote-reverse .small:before,
blockquote.pull-right .small:before {
  content: '';
}
.blockquote-reverse footer:after,
blockquote.pull-right footer:after,
.blockquote-reverse small:after,
blockquote.pull-right small:after,
.blockquote-reverse .small:after,
blockquote.pull-right .small:after {
  content: '\00A0 \2014';
}
address {
  margin-bottom: 18px;
  font-style: normal;
  line-height: 1.42857143;
}
code,
kbd,
pre,
samp {
  font-family: monospace;
}
code {
  padding: 2px 4px;
  font-size: 90%;
  color: #c7254e;
  background-color: #f9f2f4;
  border-radius: 2px;
}
kbd {
  padding: 2px 4px;
  font-size: 90%;
  color: #888;
  background-color: transparent;
  border-radius: 1px;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
}
kbd kbd {
  padding: 0;
  font-size: 100%;
  font-weight: bold;
  box-shadow: none;
}
pre {
  display: block;
  padding: 8.5px;
  margin: 0 0 9px;
  font-size: 12px;
  line-height: 1.42857143;
  word-break: break-all;
  word-wrap: break-word;
  color: #333333;
  background-color: #f5f5f5;
  border: 1px solid #ccc;
  border-radius: 2px;
}
pre code {
  padding: 0;
  font-size: inherit;
  color: inherit;
  white-space: pre-wrap;
  background-color: transparent;
  border-radius: 0;
}
.pre-scrollable {
  max-height: 340px;
  overflow-y: scroll;
}
.container {
  margin-right: auto;
  margin-left: auto;
  padding-left: 0px;
  padding-right: 0px;
}
@media (min-width: 768px) {
  .container {
    width: 768px;
  }
}
@media (min-width: 992px) {
  .container {
    width: 940px;
  }
}
@media (min-width: 1200px) {
  .container {
    width: 1140px;
  }
}
.container-fluid {
  margin-right: auto;
  margin-left: auto;
  padding-left: 0px;
  padding-right: 0px;
}
.row {
  margin-left: 0px;
  margin-right: 0px;
}
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
  position: relative;
  min-height: 1px;
  padding-left: 0px;
  padding-right: 0px;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
  float: left;
}
.col-xs-12 {
  width: 100%;
}
.col-xs-11 {
  width: 91.66666667%;
}
.col-xs-10 {
  width: 83.33333333%;
}
.col-xs-9 {
  width: 75%;
}
.col-xs-8 {
  width: 66.66666667%;
}
.col-xs-7 {
  width: 58.33333333%;
}
.col-xs-6 {
  width: 50%;
}
.col-xs-5 {
  width: 41.66666667%;
}
.col-xs-4 {
  width: 33.33333333%;
}
.col-xs-3 {
  width: 25%;
}
.col-xs-2 {
  width: 16.66666667%;
}
.col-xs-1 {
  width: 8.33333333%;
}
.col-xs-pull-12 {
  right: 100%;
}
.col-xs-pull-11 {
  right: 91.66666667%;
}
.col-xs-pull-10 {
  right: 83.33333333%;
}
.col-xs-pull-9 {
  right: 75%;
}
.col-xs-pull-8 {
  right: 66.66666667%;
}
.col-xs-pull-7 {
  right: 58.33333333%;
}
.col-xs-pull-6 {
  right: 50%;
}
.col-xs-pull-5 {
  right: 41.66666667%;
}
.col-xs-pull-4 {
  right: 33.33333333%;
}
.col-xs-pull-3 {
  right: 25%;
}
.col-xs-pull-2 {
  right: 16.66666667%;
}
.col-xs-pull-1 {
  right: 8.33333333%;
}
.col-xs-pull-0 {
  right: auto;
}
.col-xs-push-12 {
  left: 100%;
}
.col-xs-push-11 {
  left: 91.66666667%;
}
.col-xs-push-10 {
  left: 83.33333333%;
}
.col-xs-push-9 {
  left: 75%;
}
.col-xs-push-8 {
  left: 66.66666667%;
}
.col-xs-push-7 {
  left: 58.33333333%;
}
.col-xs-push-6 {
  left: 50%;
}
.col-xs-push-5 {
  left: 41.66666667%;
}
.col-xs-push-4 {
  left: 33.33333333%;
}
.col-xs-push-3 {
  left: 25%;
}
.col-xs-push-2 {
  left: 16.66666667%;
}
.col-xs-push-1 {
  left: 8.33333333%;
}
.col-xs-push-0 {
  left: auto;
}
.col-xs-offset-12 {
  margin-left: 100%;
}
.col-xs-offset-11 {
  margin-left: 91.66666667%;
}
.col-xs-offset-10 {
  margin-left: 83.33333333%;
}
.col-xs-offset-9 {
  margin-left: 75%;
}
.col-xs-offset-8 {
  margin-left: 66.66666667%;
}
.col-xs-offset-7 {
  margin-left: 58.33333333%;
}
.col-xs-offset-6 {
  margin-left: 50%;
}
.col-xs-offset-5 {
  margin-left: 41.66666667%;
}
.col-xs-offset-4 {
  margin-left: 33.33333333%;
}
.col-xs-offset-3 {
  margin-left: 25%;
}
.col-xs-offset-2 {
  margin-left: 16.66666667%;
}
.col-xs-offset-1 {
  margin-left: 8.33333333%;
}
.col-xs-offset-0 {
  margin-left: 0%;
}
@media (min-width: 768px) {
  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
    float: left;
  }
  .col-sm-12 {
    width: 100%;
  }
  .col-sm-11 {
    width: 91.66666667%;
  }
  .col-sm-10 {
    width: 83.33333333%;
  }
  .col-sm-9 {
    width: 75%;
  }
  .col-sm-8 {
    width: 66.66666667%;
  }
  .col-sm-7 {
    width: 58.33333333%;
  }
  .col-sm-6 {
    width: 50%;
  }
  .col-sm-5 {
    width: 41.66666667%;
  }
  .col-sm-4 {
    width: 33.33333333%;
  }
  .col-sm-3 {
    width: 25%;
  }
  .col-sm-2 {
    width: 16.66666667%;
  }
  .col-sm-1 {
    width: 8.33333333%;
  }
  .col-sm-pull-12 {
    right: 100%;
  }
  .col-sm-pull-11 {
    right: 91.66666667%;
  }
  .col-sm-pull-10 {
    right: 83.33333333%;
  }
  .col-sm-pull-9 {
    right: 75%;
  }
  .col-sm-pull-8 {
    right: 66.66666667%;
  }
  .col-sm-pull-7 {
    right: 58.33333333%;
  }
  .col-sm-pull-6 {
    right: 50%;
  }
  .col-sm-pull-5 {
    right: 41.66666667%;
  }
  .col-sm-pull-4 {
    right: 33.33333333%;
  }
  .col-sm-pull-3 {
    right: 25%;
  }
  .col-sm-pull-2 {
    right: 16.66666667%;
  }
  .col-sm-pull-1 {
    right: 8.33333333%;
  }
  .col-sm-pull-0 {
    right: auto;
  }
  .col-sm-push-12 {
    left: 100%;
  }
  .col-sm-push-11 {
    left: 91.66666667%;
  }
  .col-sm-push-10 {
    left: 83.33333333%;
  }
  .col-sm-push-9 {
    left: 75%;
  }
  .col-sm-push-8 {
    left: 66.66666667%;
  }
  .col-sm-push-7 {
    left: 58.33333333%;
  }
  .col-sm-push-6 {
    left: 50%;
  }
  .col-sm-push-5 {
    left: 41.66666667%;
  }
  .col-sm-push-4 {
    left: 33.33333333%;
  }
  .col-sm-push-3 {
    left: 25%;
  }
  .col-sm-push-2 {
    left: 16.66666667%;
  }
  .col-sm-push-1 {
    left: 8.33333333%;
  }
  .col-sm-push-0 {
    left: auto;
  }
  .col-sm-offset-12 {
    margin-left: 100%;
  }
  .col-sm-offset-11 {
    margin-left: 91.66666667%;
  }
  .col-sm-offset-10 {
    margin-left: 83.33333333%;
  }
  .col-sm-offset-9 {
    margin-left: 75%;
  }
  .col-sm-offset-8 {
    margin-left: 66.66666667%;
  }
  .col-sm-offset-7 {
    margin-left: 58.33333333%;
  }
  .col-sm-offset-6 {
    margin-left: 50%;
  }
  .col-sm-offset-5 {
    margin-left: 41.66666667%;
  }
  .col-sm-offset-4 {
    margin-left: 33.33333333%;
  }
  .col-sm-offset-3 {
    margin-left: 25%;
  }
  .col-sm-offset-2 {
    margin-left: 16.66666667%;
  }
  .col-sm-offset-1 {
    margin-left: 8.33333333%;
  }
  .col-sm-offset-0 {
    margin-left: 0%;
  }
}
@media (min-width: 992px) {
  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
    float: left;
  }
  .col-md-12 {
    width: 100%;
  }
  .col-md-11 {
    width: 91.66666667%;
  }
  .col-md-10 {
    width: 83.33333333%;
  }
  .col-md-9 {
    width: 75%;
  }
  .col-md-8 {
    width: 66.66666667%;
  }
  .col-md-7 {
    width: 58.33333333%;
  }
  .col-md-6 {
    width: 50%;
  }
  .col-md-5 {
    width: 41.66666667%;
  }
  .col-md-4 {
    width: 33.33333333%;
  }
  .col-md-3 {
    width: 25%;
  }
  .col-md-2 {
    width: 16.66666667%;
  }
  .col-md-1 {
    width: 8.33333333%;
  }
  .col-md-pull-12 {
    right: 100%;
  }
  .col-md-pull-11 {
    right: 91.66666667%;
  }
  .col-md-pull-10 {
    right: 83.33333333%;
  }
  .col-md-pull-9 {
    right: 75%;
  }
  .col-md-pull-8 {
    right: 66.66666667%;
  }
  .col-md-pull-7 {
    right: 58.33333333%;
  }
  .col-md-pull-6 {
    right: 50%;
  }
  .col-md-pull-5 {
    right: 41.66666667%;
  }
  .col-md-pull-4 {
    right: 33.33333333%;
  }
  .col-md-pull-3 {
    right: 25%;
  }
  .col-md-pull-2 {
    right: 16.66666667%;
  }
  .col-md-pull-1 {
    right: 8.33333333%;
  }
  .col-md-pull-0 {
    right: auto;
  }
  .col-md-push-12 {
    left: 100%;
  }
  .col-md-push-11 {
    left: 91.66666667%;
  }
  .col-md-push-10 {
    left: 83.33333333%;
  }
  .col-md-push-9 {
    left: 75%;
  }
  .col-md-push-8 {
    left: 66.66666667%;
  }
  .col-md-push-7 {
    left: 58.33333333%;
  }
  .col-md-push-6 {
    left: 50%;
  }
  .col-md-push-5 {
    left: 41.66666667%;
  }
  .col-md-push-4 {
    left: 33.33333333%;
  }
  .col-md-push-3 {
    left: 25%;
  }
  .col-md-push-2 {
    left: 16.66666667%;
  }
  .col-md-push-1 {
    left: 8.33333333%;
  }
  .col-md-push-0 {
    left: auto;
  }
  .col-md-offset-12 {
    margin-left: 100%;
  }
  .col-md-offset-11 {
    margin-left: 91.66666667%;
  }
  .col-md-offset-10 {
    margin-left: 83.33333333%;
  }
  .col-md-offset-9 {
    margin-left: 75%;
  }
  .col-md-offset-8 {
    margin-left: 66.66666667%;
  }
  .col-md-offset-7 {
    margin-left: 58.33333333%;
  }
  .col-md-offset-6 {
    margin-left: 50%;
  }
  .col-md-offset-5 {
    margin-left: 41.66666667%;
  }
  .col-md-offset-4 {
    margin-left: 33.33333333%;
  }
  .col-md-offset-3 {
    margin-left: 25%;
  }
  .col-md-offset-2 {
    margin-left: 16.66666667%;
  }
  .col-md-offset-1 {
    margin-left: 8.33333333%;
  }
  .col-md-offset-0 {
    margin-left: 0%;
  }
}
@media (min-width: 1200px) {
  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
    float: left;
  }
  .col-lg-12 {
    width: 100%;
  }
  .col-lg-11 {
    width: 91.66666667%;
  }
  .col-lg-10 {
    width: 83.33333333%;
  }
  .col-lg-9 {
    width: 75%;
  }
  .col-lg-8 {
    width: 66.66666667%;
  }
  .col-lg-7 {
    width: 58.33333333%;
  }
  .col-lg-6 {
    width: 50%;
  }
  .col-lg-5 {
    width: 41.66666667%;
  }
  .col-lg-4 {
    width: 33.33333333%;
  }
  .col-lg-3 {
    width: 25%;
  }
  .col-lg-2 {
    width: 16.66666667%;
  }
  .col-lg-1 {
    width: 8.33333333%;
  }
  .col-lg-pull-12 {
    right: 100%;
  }
  .col-lg-pull-11 {
    right: 91.66666667%;
  }
  .col-lg-pull-10 {
    right: 83.33333333%;
  }
  .col-lg-pull-9 {
    right: 75%;
  }
  .col-lg-pull-8 {
    right: 66.66666667%;
  }
  .col-lg-pull-7 {
    right: 58.33333333%;
  }
  .col-lg-pull-6 {
    right: 50%;
  }
  .col-lg-pull-5 {
    right: 41.66666667%;
  }
  .col-lg-pull-4 {
    right: 33.33333333%;
  }
  .col-lg-pull-3 {
    right: 25%;
  }
  .col-lg-pull-2 {
    right: 16.66666667%;
  }
  .col-lg-pull-1 {
    right: 8.33333333%;
  }
  .col-lg-pull-0 {
    right: auto;
  }
  .col-lg-push-12 {
    left: 100%;
  }
  .col-lg-push-11 {
    left: 91.66666667%;
  }
  .col-lg-push-10 {
    left: 83.33333333%;
  }
  .col-lg-push-9 {
    left: 75%;
  }
  .col-lg-push-8 {
    left: 66.66666667%;
  }
  .col-lg-push-7 {
    left: 58.33333333%;
  }
  .col-lg-push-6 {
    left: 50%;
  }
  .col-lg-push-5 {
    left: 41.66666667%;
  }
  .col-lg-push-4 {
    left: 33.33333333%;
  }
  .col-lg-push-3 {
    left: 25%;
  }
  .col-lg-push-2 {
    left: 16.66666667%;
  }
  .col-lg-push-1 {
    left: 8.33333333%;
  }
  .col-lg-push-0 {
    left: auto;
  }
  .col-lg-offset-12 {
    margin-left: 100%;
  }
  .col-lg-offset-11 {
    margin-left: 91.66666667%;
  }
  .col-lg-offset-10 {
    margin-left: 83.33333333%;
  }
  .col-lg-offset-9 {
    margin-left: 75%;
  }
  .col-lg-offset-8 {
    margin-left: 66.66666667%;
  }
  .col-lg-offset-7 {
    margin-left: 58.33333333%;
  }
  .col-lg-offset-6 {
    margin-left: 50%;
  }
  .col-lg-offset-5 {
    margin-left: 41.66666667%;
  }
  .col-lg-offset-4 {
    margin-left: 33.33333333%;
  }
  .col-lg-offset-3 {
    margin-left: 25%;
  }
  .col-lg-offset-2 {
    margin-left: 16.66666667%;
  }
  .col-lg-offset-1 {
    margin-left: 8.33333333%;
  }
  .col-lg-offset-0 {
    margin-left: 0%;
  }
}
table {
  background-color: transparent;
}
caption {
  padding-top: 8px;
  padding-bottom: 8px;
  color: #777777;
  text-align: left;
}
th {
  text-align: left;
}
.table {
  width: 100%;
  max-width: 100%;
  margin-bottom: 18px;
}
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
  padding: 8px;
  line-height: 1.42857143;
  vertical-align: top;
  border-top: 1px solid #ddd;
}
.table > thead > tr > th {
  vertical-align: bottom;
  border-bottom: 2px solid #ddd;
}
.table > caption + thead > tr:first-child > th,
.table > colgroup + thead > tr:first-child > th,
.table > thead:first-child > tr:first-child > th,
.table > caption + thead > tr:first-child > td,
.table > colgroup + thead > tr:first-child > td,
.table > thead:first-child > tr:first-child > td {
  border-top: 0;
}
.table > tbody + tbody {
  border-top: 2px solid #ddd;
}
.table .table {
  background-color: #fff;
}
.table-condensed > thead > tr > th,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > td {
  padding: 5px;
}
.table-bordered {
  border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
  border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
  border-bottom-width: 2px;
}
.table-striped > tbody > tr:nth-of-type(odd) {
  background-color: #f9f9f9;
}
.table-hover > tbody > tr:hover {
  background-color: #f5f5f5;
}
table col[class*="col-"] {
  position: static;
  float: none;
  display: table-column;
}
table td[class*="col-"],
table th[class*="col-"] {
  position: static;
  float: none;
  display: table-cell;
}
.table > thead > tr > td.active,
.table > tbody > tr > td.active,
.table > tfoot > tr > td.active,
.table > thead > tr > th.active,
.table > tbody > tr > th.active,
.table > tfoot > tr > th.active,
.table > thead > tr.active > td,
.table > tbody > tr.active > td,
.table > tfoot > tr.active > td,
.table > thead > tr.active > th,
.table > tbody > tr.active > th,
.table > tfoot > tr.active > th {
  background-color: #f5f5f5;
}
.table-hover > tbody > tr > td.active:hover,
.table-hover > tbody > tr > th.active:hover,
.table-hover > tbody > tr.active:hover > td,
.table-hover > tbody > tr:hover > .active,
.table-hover > tbody > tr.active:hover > th {
  background-color: #e8e8e8;
}
.table > thead > tr > td.success,
.table > tbody > tr > td.success,
.table > tfoot > tr > td.success,
.table > thead > tr > th.success,
.table > tbody > tr > th.success,
.table > tfoot > tr > th.success,
.table > thead > tr.success > td,
.table > tbody > tr.success > td,
.table > tfoot > tr.success > td,
.table > thead > tr.success > th,
.table > tbody > tr.success > th,
.table > tfoot > tr.success > th {
  background-color: #dff0d8;
}
.table-hover > tbody > tr > td.success:hover,
.table-hover > tbody > tr > th.success:hover,
.table-hover > tbody > tr.success:hover > td,
.table-hover > tbody > tr:hover > .success,
.table-hover > tbody > tr.success:hover > th {
  background-color: #d0e9c6;
}
.table > thead > tr > td.info,
.table > tbody > tr > td.info,
.table > tfoot > tr > td.info,
.table > thead > tr > th.info,
.table > tbody > tr > th.info,
.table > tfoot > tr > th.info,
.table > thead > tr.info > td,
.table > tbody > tr.info > td,
.table > tfoot > tr.info > td,
.table > thead > tr.info > th,
.table > tbody > tr.info > th,
.table > tfoot > tr.info > th {
  background-color: #d9edf7;
}
.table-hover > tbody > tr > td.info:hover,
.table-hover > tbody > tr > th.info:hover,
.table-hover > tbody > tr.info:hover > td,
.table-hover > tbody > tr:hover > .info,
.table-hover > tbody > tr.info:hover > th {
  background-color: #c4e3f3;
}
.table > thead > tr > td.warning,
.table > tbody > tr > td.warning,
.table > tfoot > tr > td.warning,
.table > thead > tr > th.warning,
.table > tbody > tr > th.warning,
.table > tfoot > tr > th.warning,
.table > thead > tr.warning > td,
.table > tbody > tr.warning > td,
.table > tfoot > tr.warning > td,
.table > thead > tr.warning > th,
.table > tbody > tr.warning > th,
.table > tfoot > tr.warning > th {
  background-color: #fcf8e3;
}
.table-hover > tbody > tr > td.warning:hover,
.table-hover > tbody > tr > th.warning:hover,
.table-hover > tbody > tr.warning:hover > td,
.table-hover > tbody > tr:hover > .warning,
.table-hover > tbody > tr.warning:hover > th {
  background-color: #faf2cc;
}
.table > thead > tr > td.danger,
.table > tbody > tr > td.danger,
.table > tfoot > tr > td.danger,
.table > thead > tr > th.danger,
.table > tbody > tr > th.danger,
.table > tfoot > tr > th.danger,
.table > thead > tr.danger > td,
.table > tbody > tr.danger > td,
.table > tfoot > tr.danger > td,
.table > thead > tr.danger > th,
.table > tbody > tr.danger > th,
.table > tfoot > tr.danger > th {
  background-color: #f2dede;
}
.table-hover > tbody > tr > td.danger:hover,
.table-hover > tbody > tr > th.danger:hover,
.table-hover > tbody > tr.danger:hover > td,
.table-hover > tbody > tr:hover > .danger,
.table-hover > tbody > tr.danger:hover > th {
  background-color: #ebcccc;
}
.table-responsive {
  overflow-x: auto;
  min-height: 0.01%;
}
@media screen and (max-width: 767px) {
  .table-responsive {
    width: 100%;
    margin-bottom: 13.5px;
    overflow-y: hidden;
    -ms-overflow-style: -ms-autohiding-scrollbar;
    border: 1px solid #ddd;
  }
  .table-responsive > .table {
    margin-bottom: 0;
  }
  .table-responsive > .table > thead > tr > th,
  .table-responsive > .table > tbody > tr > th,
  .table-responsive > .table > tfoot > tr > th,
  .table-responsive > .table > thead > tr > td,
  .table-responsive > .table > tbody > tr > td,
  .table-responsive > .table > tfoot > tr > td {
    white-space: nowrap;
  }
  .table-responsive > .table-bordered {
    border: 0;
  }
  .table-responsive > .table-bordered > thead > tr > th:first-child,
  .table-responsive > .table-bordered > tbody > tr > th:first-child,
  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
  .table-responsive > .table-bordered > thead > tr > td:first-child,
  .table-responsive > .table-bordered > tbody > tr > td:first-child,
  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
    border-left: 0;
  }
  .table-responsive > .table-bordered > thead > tr > th:last-child,
  .table-responsive > .table-bordered > tbody > tr > th:last-child,
  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
  .table-responsive > .table-bordered > thead > tr > td:last-child,
  .table-responsive > .table-bordered > tbody > tr > td:last-child,
  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
    border-right: 0;
  }
  .table-responsive > .table-bordered > tbody > tr:last-child > th,
  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
  .table-responsive > .table-bordered > tbody > tr:last-child > td,
  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
    border-bottom: 0;
  }
}
fieldset {
  padding: 0;
  margin: 0;
  border: 0;
  min-width: 0;
}
legend {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 18px;
  font-size: 19.5px;
  line-height: inherit;
  color: #333333;
  border: 0;
  border-bottom: 1px solid #e5e5e5;
}
label {
  display: inline-block;
  max-width: 100%;
  margin-bottom: 5px;
  font-weight: bold;
}
input[type="search"] {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
input[type="radio"],
input[type="checkbox"] {
  margin: 4px 0 0;
  margin-top: 1px \9;
  line-height: normal;
}
input[type="file"] {
  display: block;
}
input[type="range"] {
  display: block;
  width: 100%;
}
select[multiple],
select[size] {
  height: auto;
}
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
output {
  display: block;
  padding-top: 7px;
  font-size: 13px;
  line-height: 1.42857143;
  color: #555555;
}
.form-control {
  display: block;
  width: 100%;
  height: 32px;
  padding: 6px 12px;
  font-size: 13px;
  line-height: 1.42857143;
  color: #555555;
  background-color: #fff;
  background-image: none;
  border: 1px solid #ccc;
  border-radius: 2px;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.form-control:focus {
  border-color: #66afe9;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.form-control::-moz-placeholder {
  color: #999;
  opacity: 1;
}
.form-control:-ms-input-placeholder {
  color: #999;
}
.form-control::-webkit-input-placeholder {
  color: #999;
}
.form-control::-ms-expand {
  border: 0;
  background-color: transparent;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
  background-color: #eeeeee;
  opacity: 1;
}
.form-control[disabled],
fieldset[disabled] .form-control {
  cursor: not-allowed;
}
textarea.form-control {
  height: auto;
}
input[type="search"] {
  -webkit-appearance: none;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
  input[type="date"].form-control,
  input[type="time"].form-control,
  input[type="datetime-local"].form-control,
  input[type="month"].form-control {
    line-height: 32px;
  }
  input[type="date"].input-sm,
  input[type="time"].input-sm,
  input[type="datetime-local"].input-sm,
  input[type="month"].input-sm,
  .input-group-sm input[type="date"],
  .input-group-sm input[type="time"],
  .input-group-sm input[type="datetime-local"],
  .input-group-sm input[type="month"] {
    line-height: 30px;
  }
  input[type="date"].input-lg,
  input[type="time"].input-lg,
  input[type="datetime-local"].input-lg,
  input[type="month"].input-lg,
  .input-group-lg input[type="date"],
  .input-group-lg input[type="time"],
  .input-group-lg input[type="datetime-local"],
  .input-group-lg input[type="month"] {
    line-height: 45px;
  }
}
.form-group {
  margin-bottom: 15px;
}
.radio,
.checkbox {
  position: relative;
  display: block;
  margin-top: 10px;
  margin-bottom: 10px;
}
.radio label,
.checkbox label {
  min-height: 18px;
  padding-left: 20px;
  margin-bottom: 0;
  font-weight: normal;
  cursor: pointer;
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
  position: absolute;
  margin-left: -20px;
  margin-top: 4px \9;
}
.radio + .radio,
.checkbox + .checkbox {
  margin-top: -5px;
}
.radio-inline,
.checkbox-inline {
  position: relative;
  display: inline-block;
  padding-left: 20px;
  margin-bottom: 0;
  vertical-align: middle;
  font-weight: normal;
  cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
  margin-top: 0;
  margin-left: 10px;
}
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"].disabled,
input[type="checkbox"].disabled,
fieldset[disabled] input[type="radio"],
fieldset[disabled] input[type="checkbox"] {
  cursor: not-allowed;
}
.radio-inline.disabled,
.checkbox-inline.disabled,
fieldset[disabled] .radio-inline,
fieldset[disabled] .checkbox-inline {
  cursor: not-allowed;
}
.radio.disabled label,
.checkbox.disabled label,
fieldset[disabled] .radio label,
fieldset[disabled] .checkbox label {
  cursor: not-allowed;
}
.form-control-static {
  padding-top: 7px;
  padding-bottom: 7px;
  margin-bottom: 0;
  min-height: 31px;
}
.form-control-static.input-lg,
.form-control-static.input-sm {
  padding-left: 0;
  padding-right: 0;
}
.input-sm {
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
}
select.input-sm {
  height: 30px;
  line-height: 30px;
}
textarea.input-sm,
select[multiple].input-sm {
  height: auto;
}
.form-group-sm .form-control {
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
}
.form-group-sm select.form-control {
  height: 30px;
  line-height: 30px;
}
.form-group-sm textarea.form-control,
.form-group-sm select[multiple].form-control {
  height: auto;
}
.form-group-sm .form-control-static {
  height: 30px;
  min-height: 30px;
  padding: 6px 10px;
  font-size: 12px;
  line-height: 1.5;
}
.input-lg {
  height: 45px;
  padding: 10px 16px;
  font-size: 17px;
  line-height: 1.3333333;
  border-radius: 3px;
}
select.input-lg {
  height: 45px;
  line-height: 45px;
}
textarea.input-lg,
select[multiple].input-lg {
  height: auto;
}
.form-group-lg .form-control {
  height: 45px;
  padding: 10px 16px;
  font-size: 17px;
  line-height: 1.3333333;
  border-radius: 3px;
}
.form-group-lg select.form-control {
  height: 45px;
  line-height: 45px;
}
.form-group-lg textarea.form-control,
.form-group-lg select[multiple].form-control {
  height: auto;
}
.form-group-lg .form-control-static {
  height: 45px;
  min-height: 35px;
  padding: 11px 16px;
  font-size: 17px;
  line-height: 1.3333333;
}
.has-feedback {
  position: relative;
}
.has-feedback .form-control {
  padding-right: 40px;
}
.form-control-feedback {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 2;
  display: block;
  width: 32px;
  height: 32px;
  line-height: 32px;
  text-align: center;
  pointer-events: none;
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback,
.form-group-lg .form-control + .form-control-feedback {
  width: 45px;
  height: 45px;
  line-height: 45px;
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback,
.form-group-sm .form-control + .form-control-feedback {
  width: 30px;
  height: 30px;
  line-height: 30px;
}
.has-success .help-block,
.has-success .control-label,
.has-success .radio,
.has-success .checkbox,
.has-success .radio-inline,
.has-success .checkbox-inline,
.has-success.radio label,
.has-success.checkbox label,
.has-success.radio-inline label,
.has-success.checkbox-inline label {
  color: #3c763d;
}
.has-success .form-control {
  border-color: #3c763d;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-success .form-control:focus {
  border-color: #2b542c;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
}
.has-success .input-group-addon {
  color: #3c763d;
  border-color: #3c763d;
  background-color: #dff0d8;
}
.has-success .form-control-feedback {
  color: #3c763d;
}
.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
.has-warning .checkbox,
.has-warning .radio-inline,
.has-warning .checkbox-inline,
.has-warning.radio label,
.has-warning.checkbox label,
.has-warning.radio-inline label,
.has-warning.checkbox-inline label {
  color: #8a6d3b;
}
.has-warning .form-control {
  border-color: #8a6d3b;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-warning .form-control:focus {
  border-color: #66512c;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
}
.has-warning .input-group-addon {
  color: #8a6d3b;
  border-color: #8a6d3b;
  background-color: #fcf8e3;
}
.has-warning .form-control-feedback {
  color: #8a6d3b;
}
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline,
.has-error.radio label,
.has-error.checkbox label,
.has-error.radio-inline label,
.has-error.checkbox-inline label {
  color: #a94442;
}
.has-error .form-control {
  border-color: #a94442;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-error .form-control:focus {
  border-color: #843534;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
}
.has-error .input-group-addon {
  color: #a94442;
  border-color: #a94442;
  background-color: #f2dede;
}
.has-error .form-control-feedback {
  color: #a94442;
}
.has-feedback label ~ .form-control-feedback {
  top: 23px;
}
.has-feedback label.sr-only ~ .form-control-feedback {
  top: 0;
}
.help-block {
  display: block;
  margin-top: 5px;
  margin-bottom: 10px;
  color: #404040;
}
@media (min-width: 768px) {
  .form-inline .form-group {
    display: inline-block;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .form-control {
    display: inline-block;
    width: auto;
    vertical-align: middle;
  }
  .form-inline .form-control-static {
    display: inline-block;
  }
  .form-inline .input-group {
    display: inline-table;
    vertical-align: middle;
  }
  .form-inline .input-group .input-group-addon,
  .form-inline .input-group .input-group-btn,
  .form-inline .input-group .form-control {
    width: auto;
  }
  .form-inline .input-group > .form-control {
    width: 100%;
  }
  .form-inline .control-label {
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .radio,
  .form-inline .checkbox {
    display: inline-block;
    margin-top: 0;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .radio label,
  .form-inline .checkbox label {
    padding-left: 0;
  }
  .form-inline .radio input[type="radio"],
  .form-inline .checkbox input[type="checkbox"] {
    position: relative;
    margin-left: 0;
  }
  .form-inline .has-feedback .form-control-feedback {
    top: 0;
  }
}
.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 7px;
}
.form-horizontal .radio,
.form-horizontal .checkbox {
  min-height: 25px;
}
.form-horizontal .form-group {
  margin-left: 0px;
  margin-right: 0px;
}
@media (min-width: 768px) {
  .form-horizontal .control-label {
    text-align: right;
    margin-bottom: 0;
    padding-top: 7px;
  }
}
.form-horizontal .has-feedback .form-control-feedback {
  right: 0px;
}
@media (min-width: 768px) {
  .form-horizontal .form-group-lg .control-label {
    padding-top: 11px;
    font-size: 17px;
  }
}
@media (min-width: 768px) {
  .form-horizontal .form-group-sm .control-label {
    padding-top: 6px;
    font-size: 12px;
  }
}
.btn {
  display: inline-block;
  margin-bottom: 0;
  font-weight: normal;
  text-align: center;
  vertical-align: middle;
  touch-action: manipulation;
  cursor: pointer;
  background-image: none;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 12px;
  font-size: 13px;
  line-height: 1.42857143;
  border-radius: 2px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
.btn:hover,
.btn:focus,
.btn.focus {
  color: #333;
  text-decoration: none;
}
.btn:active,
.btn.active {
  outline: 0;
  background-image: none;
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
  cursor: not-allowed;
  opacity: 0.65;
  filter: alpha(opacity=65);
  -webkit-box-shadow: none;
  box-shadow: none;
}
a.btn.disabled,
fieldset[disabled] a.btn {
  pointer-events: none;
}
.btn-default {
  color: #333;
  background-color: #fff;
  border-color: #ccc;
}
.btn-default:focus,
.btn-default.focus {
  color: #333;
  background-color: #e6e6e6;
  border-color: #8c8c8c;
}
.btn-default:hover {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.btn-default:active:hover,
.btn-default.active:hover,
.open > .dropdown-toggle.btn-default:hover,
.btn-default:active:focus,
.btn-default.active:focus,
.open > .dropdown-toggle.btn-default:focus,
.btn-default:active.focus,
.btn-default.active.focus,
.open > .dropdown-toggle.btn-default.focus {
  color: #333;
  background-color: #d4d4d4;
  border-color: #8c8c8c;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
  background-image: none;
}
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus {
  background-color: #fff;
  border-color: #ccc;
}
.btn-default .badge {
  color: #fff;
  background-color: #333;
}
.btn-primary {
  color: #fff;
  background-color: #337ab7;
  border-color: #2e6da4;
}
.btn-primary:focus,
.btn-primary.focus {
  color: #fff;
  background-color: #286090;
  border-color: #122b40;
}
.btn-primary:hover {
  color: #fff;
  background-color: #286090;
  border-color: #204d74;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
  color: #fff;
  background-color: #286090;
  border-color: #204d74;
}
.btn-primary:active:hover,
.btn-primary.active:hover,
.open > .dropdown-toggle.btn-primary:hover,
.btn-primary:active:focus,
.btn-primary.active:focus,
.open > .dropdown-toggle.btn-primary:focus,
.btn-primary:active.focus,
.btn-primary.active.focus,
.open > .dropdown-toggle.btn-primary.focus {
  color: #fff;
  background-color: #204d74;
  border-color: #122b40;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
  background-image: none;
}
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus {
  background-color: #337ab7;
  border-color: #2e6da4;
}
.btn-primary .badge {
  color: #337ab7;
  background-color: #fff;
}
.btn-success {
  color: #fff;
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.btn-success:focus,
.btn-success.focus {
  color: #fff;
  background-color: #449d44;
  border-color: #255625;
}
.btn-success:hover {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}
.btn-success:active:hover,
.btn-success.active:hover,
.open > .dropdown-toggle.btn-success:hover,
.btn-success:active:focus,
.btn-success.active:focus,
.open > .dropdown-toggle.btn-success:focus,
.btn-success:active.focus,
.btn-success.active.focus,
.open > .dropdown-toggle.btn-success.focus {
  color: #fff;
  background-color: #398439;
  border-color: #255625;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
  background-image: none;
}
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus {
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.btn-success .badge {
  color: #5cb85c;
  background-color: #fff;
}
.btn-info {
  color: #fff;
  background-color: #5bc0de;
  border-color: #46b8da;
}
.btn-info:focus,
.btn-info.focus {
  color: #fff;
  background-color: #31b0d5;
  border-color: #1b6d85;
}
.btn-info:hover {
  color: #fff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
  color: #fff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.btn-info:active:hover,
.btn-info.active:hover,
.open > .dropdown-toggle.btn-info:hover,
.btn-info:active:focus,
.btn-info.active:focus,
.open > .dropdown-toggle.btn-info:focus,
.btn-info:active.focus,
.btn-info.active.focus,
.open > .dropdown-toggle.btn-info.focus {
  color: #fff;
  background-color: #269abc;
  border-color: #1b6d85;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
  background-image: none;
}
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus {
  background-color: #5bc0de;
  border-color: #46b8da;
}
.btn-info .badge {
  color: #5bc0de;
  background-color: #fff;
}
.btn-warning {
  color: #fff;
  background-color: #f0ad4e;
  border-color: #eea236;
}
.btn-warning:focus,
.btn-warning.focus {
  color: #fff;
  background-color: #ec971f;
  border-color: #985f0d;
}
.btn-warning:hover {
  color: #fff;
  background-color: #ec971f;
  border-color: #d58512;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
  color: #fff;
  background-color: #ec971f;
  border-color: #d58512;
}
.btn-warning:active:hover,
.btn-warning.active:hover,
.open > .dropdown-toggle.btn-warning:hover,
.btn-warning:active:focus,
.btn-warning.active:focus,
.open > .dropdown-toggle.btn-warning:focus,
.btn-warning:active.focus,
.btn-warning.active.focus,
.open > .dropdown-toggle.btn-warning.focus {
  color: #fff;
  background-color: #d58512;
  border-color: #985f0d;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
  background-image: none;
}
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus {
  background-color: #f0ad4e;
  border-color: #eea236;
}
.btn-warning .badge {
  color: #f0ad4e;
  background-color: #fff;
}
.btn-danger {
  color: #fff;
  background-color: #d9534f;
  border-color: #d43f3a;
}
.btn-danger:focus,
.btn-danger.focus {
  color: #fff;
  background-color: #c9302c;
  border-color: #761c19;
}
.btn-danger:hover {
  color: #fff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
  color: #fff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.btn-danger:active:hover,
.btn-danger.active:hover,
.open > .dropdown-toggle.btn-danger:hover,
.btn-danger:active:focus,
.btn-danger.active:focus,
.open > .dropdown-toggle.btn-danger:focus,
.btn-danger:active.focus,
.btn-danger.active.focus,
.open > .dropdown-toggle.btn-danger.focus {
  color: #fff;
  background-color: #ac2925;
  border-color: #761c19;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
  background-image: none;
}
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus {
  background-color: #d9534f;
  border-color: #d43f3a;
}
.btn-danger .badge {
  color: #d9534f;
  background-color: #fff;
}
.btn-link {
  color: #337ab7;
  font-weight: normal;
  border-radius: 0;
}
.btn-link,
.btn-link:active,
.btn-link.active,
.btn-link[disabled],
fieldset[disabled] .btn-link {
  background-color: transparent;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn-link,
.btn-link:hover,
.btn-link:focus,
.btn-link:active {
  border-color: transparent;
}
.btn-link:hover,
.btn-link:focus {
  color: #23527c;
  text-decoration: underline;
  background-color: transparent;
}
.btn-link[disabled]:hover,
fieldset[disabled] .btn-link:hover,
.btn-link[disabled]:focus,
fieldset[disabled] .btn-link:focus {
  color: #777777;
  text-decoration: none;
}
.btn-lg,
.btn-group-lg > .btn {
  padding: 10px 16px;
  font-size: 17px;
  line-height: 1.3333333;
  border-radius: 3px;
}
.btn-sm,
.btn-group-sm > .btn {
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
}
.btn-xs,
.btn-group-xs > .btn {
  padding: 1px 5px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
}
.btn-block {
  display: block;
  width: 100%;
}
.btn-block + .btn-block {
  margin-top: 5px;
}
input[type="submit"].btn-block,
input[type="reset"].btn-block,
input[type="button"].btn-block {
  width: 100%;
}
.fade {
  opacity: 0;
  -webkit-transition: opacity 0.15s linear;
  -o-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
}
.fade.in {
  opacity: 1;
}
.collapse {
  display: none;
}
.collapse.in {
  display: block;
}
tr.collapse.in {
  display: table-row;
}
tbody.collapse.in {
  display: table-row-group;
}
.collapsing {
  position: relative;
  height: 0;
  overflow: hidden;
  -webkit-transition-property: height, visibility;
  transition-property: height, visibility;
  -webkit-transition-duration: 0.35s;
  transition-duration: 0.35s;
  -webkit-transition-timing-function: ease;
  transition-timing-function: ease;
}
.caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  vertical-align: middle;
  border-top: 4px dashed;
  border-top: 4px solid \9;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}
.dropup,
.dropdown {
  position: relative;
}
.dropdown-toggle:focus {
  outline: 0;
}
.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: none;
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  list-style: none;
  font-size: 13px;
  text-align: left;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 2px;
  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  background-clip: padding-box;
}
.dropdown-menu.pull-right {
  right: 0;
  left: auto;
}
.dropdown-menu .divider {
  height: 1px;
  margin: 8px 0;
  overflow: hidden;
  background-color: #e5e5e5;
}
.dropdown-menu > li > a {
  display: block;
  padding: 3px 20px;
  clear: both;
  font-weight: normal;
  line-height: 1.42857143;
  color: #333333;
  white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
  text-decoration: none;
  color: #262626;
  background-color: #f5f5f5;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
  color: #fff;
  text-decoration: none;
  outline: 0;
  background-color: #337ab7;
}
.dropdown-menu > .disabled > a,
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
  color: #777777;
}
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
  text-decoration: none;
  background-color: transparent;
  background-image: none;
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  cursor: not-allowed;
}
.open > .dropdown-menu {
  display: block;
}
.open > a {
  outline: 0;
}
.dropdown-menu-right {
  left: auto;
  right: 0;
}
.dropdown-menu-left {
  left: 0;
  right: auto;
}
.dropdown-header {
  display: block;
  padding: 3px 20px;
  font-size: 12px;
  line-height: 1.42857143;
  color: #777777;
  white-space: nowrap;
}
.dropdown-backdrop {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  z-index: 990;
}
.pull-right > .dropdown-menu {
  right: 0;
  left: auto;
}
.dropup .caret,
.navbar-fixed-bottom .dropdown .caret {
  border-top: 0;
  border-bottom: 4px dashed;
  border-bottom: 4px solid \9;
  content: "";
}
.dropup .dropdown-menu,
.navbar-fixed-bottom .dropdown .dropdown-menu {
  top: auto;
  bottom: 100%;
  margin-bottom: 2px;
}
@media (min-width: 541px) {
  .navbar-right .dropdown-menu {
    left: auto;
    right: 0;
  }
  .navbar-right .dropdown-menu-left {
    left: 0;
    right: auto;
  }
}
.btn-group,
.btn-group-vertical {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}
.btn-group > .btn,
.btn-group-vertical > .btn {
  position: relative;
  float: left;
}
.btn-group > .btn:hover,
.btn-group-vertical > .btn:hover,
.btn-group > .btn:focus,
.btn-group-vertical > .btn:focus,
.btn-group > .btn:active,
.btn-group-vertical > .btn:active,
.btn-group > .btn.active,
.btn-group-vertical > .btn.active {
  z-index: 2;
}
.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
.btn-group .btn-group + .btn,
.btn-group .btn-group + .btn-group {
  margin-left: -1px;
}
.btn-toolbar {
  margin-left: -5px;
}
.btn-toolbar .btn,
.btn-toolbar .btn-group,
.btn-toolbar .input-group {
  float: left;
}
.btn-toolbar > .btn,
.btn-toolbar > .btn-group,
.btn-toolbar > .input-group {
  margin-left: 5px;
}
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
  border-radius: 0;
}
.btn-group > .btn:first-child {
  margin-left: 0;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}
.btn-group > .btn-group {
  float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}
.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
  outline: 0;
}
.btn-group > .btn + .dropdown-toggle {
  padding-left: 8px;
  padding-right: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
  padding-left: 12px;
  padding-right: 12px;
}
.btn-group.open .dropdown-toggle {
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-group.open .dropdown-toggle.btn-link {
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn .caret {
  margin-left: 0;
}
.btn-lg .caret {
  border-width: 5px 5px 0;
  border-bottom-width: 0;
}
.dropup .btn-lg .caret {
  border-width: 0 5px 5px;
}
.btn-group-vertical > .btn,
.btn-group-vertical > .btn-group,
.btn-group-vertical > .btn-group > .btn {
  display: block;
  float: none;
  width: 100%;
  max-width: 100%;
}
.btn-group-vertical > .btn-group > .btn {
  float: none;
}
.btn-group-vertical > .btn + .btn,
.btn-group-vertical > .btn + .btn-group,
.btn-group-vertical > .btn-group + .btn,
.btn-group-vertical > .btn-group + .btn-group {
  margin-top: -1px;
  margin-left: 0;
}
.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
  border-radius: 0;
}
.btn-group-vertical > .btn:first-child:not(:last-child) {
  border-top-right-radius: 2px;
  border-top-left-radius: 2px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn:last-child:not(:first-child) {
  border-top-right-radius: 0;
  border-top-left-radius: 0;
  border-bottom-right-radius: 2px;
  border-bottom-left-radius: 2px;
}
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}
.btn-group-justified {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
}
.btn-group-justified > .btn,
.btn-group-justified > .btn-group {
  float: none;
  display: table-cell;
  width: 1%;
}
.btn-group-justified > .btn-group .btn {
  width: 100%;
}
.btn-group-justified > .btn-group .dropdown-menu {
  left: auto;
}
[data-toggle="buttons"] > .btn input[type="radio"],
[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
[data-toggle="buttons"] > .btn input[type="checkbox"],
[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
  position: absolute;
  clip: rect(0, 0, 0, 0);
  pointer-events: none;
}
.input-group {
  position: relative;
  display: table;
  border-collapse: separate;
}
.input-group[class*="col-"] {
  float: none;
  padding-left: 0;
  padding-right: 0;
}
.input-group .form-control {
  position: relative;
  z-index: 2;
  float: left;
  width: 100%;
  margin-bottom: 0;
}
.input-group .form-control:focus {
  z-index: 3;
}
.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
  height: 45px;
  padding: 10px 16px;
  font-size: 17px;
  line-height: 1.3333333;
  border-radius: 3px;
}
select.input-group-lg > .form-control,
select.input-group-lg > .input-group-addon,
select.input-group-lg > .input-group-btn > .btn {
  height: 45px;
  line-height: 45px;
}
textarea.input-group-lg > .form-control,
textarea.input-group-lg > .input-group-addon,
textarea.input-group-lg > .input-group-btn > .btn,
select[multiple].input-group-lg > .form-control,
select[multiple].input-group-lg > .input-group-addon,
select[multiple].input-group-lg > .input-group-btn > .btn {
  height: auto;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
}
select.input-group-sm > .form-control,
select.input-group-sm > .input-group-addon,
select.input-group-sm > .input-group-btn > .btn {
  height: 30px;
  line-height: 30px;
}
textarea.input-group-sm > .form-control,
textarea.input-group-sm > .input-group-addon,
textarea.input-group-sm > .input-group-btn > .btn,
select[multiple].input-group-sm > .form-control,
select[multiple].input-group-sm > .input-group-addon,
select[multiple].input-group-sm > .input-group-btn > .btn {
  height: auto;
}
.input-group-addon,
.input-group-btn,
.input-group .form-control {
  display: table-cell;
}
.input-group-addon:not(:first-child):not(:last-child),
.input-group-btn:not(:first-child):not(:last-child),
.input-group .form-control:not(:first-child):not(:last-child) {
  border-radius: 0;
}
.input-group-addon,
.input-group-btn {
  width: 1%;
  white-space: nowrap;
  vertical-align: middle;
}
.input-group-addon {
  padding: 6px 12px;
  font-size: 13px;
  font-weight: normal;
  line-height: 1;
  color: #555555;
  text-align: center;
  background-color: #eeeeee;
  border: 1px solid #ccc;
  border-radius: 2px;
}
.input-group-addon.input-sm {
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 1px;
}
.input-group-addon.input-lg {
  padding: 10px 16px;
  font-size: 17px;
  border-radius: 3px;
}
.input-group-addon input[type="radio"],
.input-group-addon input[type="checkbox"] {
  margin-top: 0;
}
.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}
.input-group-addon:first-child {
  border-right: 0;
}
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}
.input-group-addon:last-child {
  border-left: 0;
}
.input-group-btn {
  position: relative;
  font-size: 0;
  white-space: nowrap;
}
.input-group-btn > .btn {
  position: relative;
}
.input-group-btn > .btn + .btn {
  margin-left: -1px;
}
.input-group-btn > .btn:hover,
.input-group-btn > .btn:focus,
.input-group-btn > .btn:active {
  z-index: 2;
}
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group {
  margin-right: -1px;
}
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group {
  z-index: 2;
  margin-left: -1px;
}
.nav {
  margin-bottom: 0;
  padding-left: 0;
  list-style: none;
}
.nav > li {
  position: relative;
  display: block;
}
.nav > li > a {
  position: relative;
  display: block;
  padding: 10px 15px;
}
.nav > li > a:hover,
.nav > li > a:focus {
  text-decoration: none;
  background-color: #eeeeee;
}
.nav > li.disabled > a {
  color: #777777;
}
.nav > li.disabled > a:hover,
.nav > li.disabled > a:focus {
  color: #777777;
  text-decoration: none;
  background-color: transparent;
  cursor: not-allowed;
}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
  background-color: #eeeeee;
  border-color: #337ab7;
}
.nav .nav-divider {
  height: 1px;
  margin: 8px 0;
  overflow: hidden;
  background-color: #e5e5e5;
}
.nav > li > a > img {
  max-width: none;
}
.nav-tabs {
  border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
  float: left;
  margin-bottom: -1px;
}
.nav-tabs > li > a {
  margin-right: 2px;
  line-height: 1.42857143;
  border: 1px solid transparent;
  border-radius: 2px 2px 0 0;
}
.nav-tabs > li > a:hover {
  border-color: #eeeeee #eeeeee #ddd;
}
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
  color: #555555;
  background-color: #fff;
  border: 1px solid #ddd;
  border-bottom-color: transparent;
  cursor: default;
}
.nav-tabs.nav-justified {
  width: 100%;
  border-bottom: 0;
}
.nav-tabs.nav-justified > li {
  float: none;
}
.nav-tabs.nav-justified > li > a {
  text-align: center;
  margin-bottom: 5px;
}
.nav-tabs.nav-justified > .dropdown .dropdown-menu {
  top: auto;
  left: auto;
}
@media (min-width: 768px) {
  .nav-tabs.nav-justified > li {
    display: table-cell;
    width: 1%;
  }
  .nav-tabs.nav-justified > li > a {
    margin-bottom: 0;
  }
}
.nav-tabs.nav-justified > li > a {
  margin-right: 0;
  border-radius: 2px;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
  border: 1px solid #ddd;
}
@media (min-width: 768px) {
  .nav-tabs.nav-justified > li > a {
    border-bottom: 1px solid #ddd;
    border-radius: 2px 2px 0 0;
  }
  .nav-tabs.nav-justified > .active > a,
  .nav-tabs.nav-justified > .active > a:hover,
  .nav-tabs.nav-justified > .active > a:focus {
    border-bottom-color: #fff;
  }
}
.nav-pills > li {
  float: left;
}
.nav-pills > li > a {
  border-radius: 2px;
}
.nav-pills > li + li {
  margin-left: 2px;
}
.nav-pills > li.active > a,
.nav-pills > li.active > a:hover,
.nav-pills > li.active > a:focus {
  color: #fff;
  background-color: #337ab7;
}
.nav-stacked > li {
  float: none;
}
.nav-stacked > li + li {
  margin-top: 2px;
  margin-left: 0;
}
.nav-justified {
  width: 100%;
}
.nav-justified > li {
  float: none;
}
.nav-justified > li > a {
  text-align: center;
  margin-bottom: 5px;
}
.nav-justified > .dropdown .dropdown-menu {
  top: auto;
  left: auto;
}
@media (min-width: 768px) {
  .nav-justified > li {
    display: table-cell;
    width: 1%;
  }
  .nav-justified > li > a {
    margin-bottom: 0;
  }
}
.nav-tabs-justified {
  border-bottom: 0;
}
.nav-tabs-justified > li > a {
  margin-right: 0;
  border-radius: 2px;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
  border: 1px solid #ddd;
}
@media (min-width: 768px) {
  .nav-tabs-justified > li > a {
    border-bottom: 1px solid #ddd;
    border-radius: 2px 2px 0 0;
  }
  .nav-tabs-justified > .active > a,
  .nav-tabs-justified > .active > a:hover,
  .nav-tabs-justified > .active > a:focus {
    border-bottom-color: #fff;
  }
}
.tab-content > .tab-pane {
  display: none;
}
.tab-content > .active {
  display: block;
}
.nav-tabs .dropdown-menu {
  margin-top: -1px;
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}
.navbar {
  position: relative;
  min-height: 30px;
  margin-bottom: 18px;
  border: 1px solid transparent;
}
@media (min-width: 541px) {
  .navbar {
    border-radius: 2px;
  }
}
@media (min-width: 541px) {
  .navbar-header {
    float: left;
  }
}
.navbar-collapse {
  overflow-x: visible;
  padding-right: 0px;
  padding-left: 0px;
  border-top: 1px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
  -webkit-overflow-scrolling: touch;
}
.navbar-collapse.in {
  overflow-y: auto;
}
@media (min-width: 541px) {
  .navbar-collapse {
    width: auto;
    border-top: 0;
    box-shadow: none;
  }
  .navbar-collapse.collapse {
    display: block !important;
    height: auto !important;
    padding-bottom: 0;
    overflow: visible !important;
  }
  .navbar-collapse.in {
    overflow-y: visible;
  }
  .navbar-fixed-top .navbar-collapse,
  .navbar-static-top .navbar-collapse,
  .navbar-fixed-bottom .navbar-collapse {
    padding-left: 0;
    padding-right: 0;
  }
}
.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
  max-height: 340px;
}
@media (max-device-width: 540px) and (orientation: landscape) {
  .navbar-fixed-top .navbar-collapse,
  .navbar-fixed-bottom .navbar-collapse {
    max-height: 200px;
  }
}
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
  margin-right: 0px;
  margin-left: 0px;
}
@media (min-width: 541px) {
  .container > .navbar-header,
  .container-fluid > .navbar-header,
  .container > .navbar-collapse,
  .container-fluid > .navbar-collapse {
    margin-right: 0;
    margin-left: 0;
  }
}
.navbar-static-top {
  z-index: 1000;
  border-width: 0 0 1px;
}
@media (min-width: 541px) {
  .navbar-static-top {
    border-radius: 0;
  }
}
.navbar-fixed-top,
.navbar-fixed-bottom {
  position: fixed;
  right: 0;
  left: 0;
  z-index: 1030;
}
@media (min-width: 541px) {
  .navbar-fixed-top,
  .navbar-fixed-bottom {
    border-radius: 0;
  }
}
.navbar-fixed-top {
  top: 0;
  border-width: 0 0 1px;
}
.navbar-fixed-bottom {
  bottom: 0;
  margin-bottom: 0;
  border-width: 1px 0 0;
}
.navbar-brand {
  float: left;
  padding: 6px 0px;
  font-size: 17px;
  line-height: 18px;
  height: 30px;
}
.navbar-brand:hover,
.navbar-brand:focus {
  text-decoration: none;
}
.navbar-brand > img {
  display: block;
}
@media (min-width: 541px) {
  .navbar > .container .navbar-brand,
  .navbar > .container-fluid .navbar-brand {
    margin-left: 0px;
  }
}
.navbar-toggle {
  position: relative;
  float: right;
  margin-right: 0px;
  padding: 9px 10px;
  margin-top: -2px;
  margin-bottom: -2px;
  background-color: transparent;
  background-image: none;
  border: 1px solid transparent;
  border-radius: 2px;
}
.navbar-toggle:focus {
  outline: 0;
}
.navbar-toggle .icon-bar {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
}
.navbar-toggle .icon-bar + .icon-bar {
  margin-top: 4px;
}
@media (min-width: 541px) {
  .navbar-toggle {
    display: none;
  }
}
.navbar-nav {
  margin: 3px 0px;
}
.navbar-nav > li > a {
  padding-top: 10px;
  padding-bottom: 10px;
  line-height: 18px;
}
@media (max-width: 540px) {
  .navbar-nav .open .dropdown-menu {
    position: static;
    float: none;
    width: auto;
    margin-top: 0;
    background-color: transparent;
    border: 0;
    box-shadow: none;
  }
  .navbar-nav .open .dropdown-menu > li > a,
  .navbar-nav .open .dropdown-menu .dropdown-header {
    padding: 5px 15px 5px 25px;
  }
  .navbar-nav .open .dropdown-menu > li > a {
    line-height: 18px;
  }
  .navbar-nav .open .dropdown-menu > li > a:hover,
  .navbar-nav .open .dropdown-menu > li > a:focus {
    background-image: none;
  }
}
@media (min-width: 541px) {
  .navbar-nav {
    float: left;
    margin: 0;
  }
  .navbar-nav > li {
    float: left;
  }
  .navbar-nav > li > a {
    padding-top: 6px;
    padding-bottom: 6px;
  }
}
.navbar-form {
  margin-left: 0px;
  margin-right: 0px;
  padding: 10px 0px;
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
  margin-top: -1px;
  margin-bottom: -1px;
}
@media (min-width: 768px) {
  .navbar-form .form-group {
    display: inline-block;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .navbar-form .form-control {
    display: inline-block;
    width: auto;
    vertical-align: middle;
  }
  .navbar-form .form-control-static {
    display: inline-block;
  }
  .navbar-form .input-group {
    display: inline-table;
    vertical-align: middle;
  }
  .navbar-form .input-group .input-group-addon,
  .navbar-form .input-group .input-group-btn,
  .navbar-form .input-group .form-control {
    width: auto;
  }
  .navbar-form .input-group > .form-control {
    width: 100%;
  }
  .navbar-form .control-label {
    margin-bottom: 0;
    vertical-align: middle;
  }
  .navbar-form .radio,
  .navbar-form .checkbox {
    display: inline-block;
    margin-top: 0;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .navbar-form .radio label,
  .navbar-form .checkbox label {
    padding-left: 0;
  }
  .navbar-form .radio input[type="radio"],
  .navbar-form .checkbox input[type="checkbox"] {
    position: relative;
    margin-left: 0;
  }
  .navbar-form .has-feedback .form-control-feedback {
    top: 0;
  }
}
@media (max-width: 540px) {
  .navbar-form .form-group {
    margin-bottom: 5px;
  }
  .navbar-form .form-group:last-child {
    margin-bottom: 0;
  }
}
@media (min-width: 541px) {
  .navbar-form {
    width: auto;
    border: 0;
    margin-left: 0;
    margin-right: 0;
    padding-top: 0;
    padding-bottom: 0;
    -webkit-box-shadow: none;
    box-shadow: none;
  }
}
.navbar-nav > li > .dropdown-menu {
  margin-top: 0;
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}
.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
  margin-bottom: 0;
  border-top-right-radius: 2px;
  border-top-left-radius: 2px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.navbar-btn {
  margin-top: -1px;
  margin-bottom: -1px;
}
.navbar-btn.btn-sm {
  margin-top: 0px;
  margin-bottom: 0px;
}
.navbar-btn.btn-xs {
  margin-top: 4px;
  margin-bottom: 4px;
}
.navbar-text {
  margin-top: 6px;
  margin-bottom: 6px;
}
@media (min-width: 541px) {
  .navbar-text {
    float: left;
    margin-left: 0px;
    margin-right: 0px;
  }
}
@media (min-width: 541px) {
  .navbar-left {
    float: left !important;
    float: left;
  }
  .navbar-right {
    float: right !important;
    float: right;
    margin-right: 0px;
  }
  .navbar-right ~ .navbar-right {
    margin-right: 0;
  }
}
.navbar-default {
  background-color: #f8f8f8;
  border-color: #e7e7e7;
}
.navbar-default .navbar-brand {
  color: #777;
}
.navbar-default .navbar-brand:hover,
.navbar-default .navbar-brand:focus {
  color: #5e5e5e;
  background-color: transparent;
}
.navbar-default .navbar-text {
  color: #777;
}
.navbar-default .navbar-nav > li > a {
  color: #777;
}
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus {
  color: #333;
  background-color: transparent;
}
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > .active > a:hover,
.navbar-default .navbar-nav > .active > a:focus {
  color: #555;
  background-color: #e7e7e7;
}
.navbar-default .navbar-nav > .disabled > a,
.navbar-default .navbar-nav > .disabled > a:hover,
.navbar-default .navbar-nav > .disabled > a:focus {
  color: #ccc;
  background-color: transparent;
}
.navbar-default .navbar-toggle {
  border-color: #ddd;
}
.navbar-default .navbar-toggle:hover,
.navbar-default .navbar-toggle:focus {
  background-color: #ddd;
}
.navbar-default .navbar-toggle .icon-bar {
  background-color: #888;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
  border-color: #e7e7e7;
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .open > a:hover,
.navbar-default .navbar-nav > .open > a:focus {
  background-color: #e7e7e7;
  color: #555;
}
@media (max-width: 540px) {
  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
    color: #777;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
    color: #333;
    background-color: transparent;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
    color: #555;
    background-color: #e7e7e7;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
    color: #ccc;
    background-color: transparent;
  }
}
.navbar-default .navbar-link {
  color: #777;
}
.navbar-default .navbar-link:hover {
  color: #333;
}
.navbar-default .btn-link {
  color: #777;
}
.navbar-default .btn-link:hover,
.navbar-default .btn-link:focus {
  color: #333;
}
.navbar-default .btn-link[disabled]:hover,
fieldset[disabled] .navbar-default .btn-link:hover,
.navbar-default .btn-link[disabled]:focus,
fieldset[disabled] .navbar-default .btn-link:focus {
  color: #ccc;
}
.navbar-inverse {
  background-color: #222;
  border-color: #080808;
}
.navbar-inverse .navbar-brand {
  color: #9d9d9d;
}
.navbar-inverse .navbar-brand:hover,
.navbar-inverse .navbar-brand:focus {
  color: #fff;
  background-color: transparent;
}
.navbar-inverse .navbar-text {
  color: #9d9d9d;
}
.navbar-inverse .navbar-nav > li > a {
  color: #9d9d9d;
}
.navbar-inverse .navbar-nav > li > a:hover,
.navbar-inverse .navbar-nav > li > a:focus {
  color: #fff;
  background-color: transparent;
}
.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
  color: #fff;
  background-color: #080808;
}
.navbar-inverse .navbar-nav > .disabled > a,
.navbar-inverse .navbar-nav > .disabled > a:hover,
.navbar-inverse .navbar-nav > .disabled > a:focus {
  color: #444;
  background-color: transparent;
}
.navbar-inverse .navbar-toggle {
  border-color: #333;
}
.navbar-inverse .navbar-toggle:hover,
.navbar-inverse .navbar-toggle:focus {
  background-color: #333;
}
.navbar-inverse .navbar-toggle .icon-bar {
  background-color: #fff;
}
.navbar-inverse .navbar-collapse,
.navbar-inverse .navbar-form {
  border-color: #101010;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .open > a:hover,
.navbar-inverse .navbar-nav > .open > a:focus {
  background-color: #080808;
  color: #fff;
}
@media (max-width: 540px) {
  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
    border-color: #080808;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
    background-color: #080808;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
    color: #9d9d9d;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
    color: #fff;
    background-color: transparent;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
    color: #fff;
    background-color: #080808;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
    color: #444;
    background-color: transparent;
  }
}
.navbar-inverse .navbar-link {
  color: #9d9d9d;
}
.navbar-inverse .navbar-link:hover {
  color: #fff;
}
.navbar-inverse .btn-link {
  color: #9d9d9d;
}
.navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link:focus {
  color: #fff;
}
.navbar-inverse .btn-link[disabled]:hover,
fieldset[disabled] .navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link[disabled]:focus,
fieldset[disabled] .navbar-inverse .btn-link:focus {
  color: #444;
}
.breadcrumb {
  padding: 8px 15px;
  margin-bottom: 18px;
  list-style: none;
  background-color: #f5f5f5;
  border-radius: 2px;
}
.breadcrumb > li {
  display: inline-block;
}
.breadcrumb > li + li:before {
  content: "/\00a0";
  padding: 0 5px;
  color: #5e5e5e;
}
.breadcrumb > .active {
  color: #777777;
}
.pagination {
  display: inline-block;
  padding-left: 0;
  margin: 18px 0;
  border-radius: 2px;
}
.pagination > li {
  display: inline;
}
.pagination > li > a,
.pagination > li > span {
  position: relative;
  float: left;
  padding: 6px 12px;
  line-height: 1.42857143;
  text-decoration: none;
  color: #337ab7;
  background-color: #fff;
  border: 1px solid #ddd;
  margin-left: -1px;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
  margin-left: 0;
  border-bottom-left-radius: 2px;
  border-top-left-radius: 2px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
  border-bottom-right-radius: 2px;
  border-top-right-radius: 2px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
  z-index: 2;
  color: #23527c;
  background-color: #eeeeee;
  border-color: #ddd;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus {
  z-index: 3;
  color: #fff;
  background-color: #337ab7;
  border-color: #337ab7;
  cursor: default;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
  color: #777777;
  background-color: #fff;
  border-color: #ddd;
  cursor: not-allowed;
}
.pagination-lg > li > a,
.pagination-lg > li > span {
  padding: 10px 16px;
  font-size: 17px;
  line-height: 1.3333333;
}
.pagination-lg > li:first-child > a,
.pagination-lg > li:first-child > span {
  border-bottom-left-radius: 3px;
  border-top-left-radius: 3px;
}
.pagination-lg > li:last-child > a,
.pagination-lg > li:last-child > span {
  border-bottom-right-radius: 3px;
  border-top-right-radius: 3px;
}
.pagination-sm > li > a,
.pagination-sm > li > span {
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
}
.pagination-sm > li:first-child > a,
.pagination-sm > li:first-child > span {
  border-bottom-left-radius: 1px;
  border-top-left-radius: 1px;
}
.pagination-sm > li:last-child > a,
.pagination-sm > li:last-child > span {
  border-bottom-right-radius: 1px;
  border-top-right-radius: 1px;
}
.pager {
  padding-left: 0;
  margin: 18px 0;
  list-style: none;
  text-align: center;
}
.pager li {
  display: inline;
}
.pager li > a,
.pager li > span {
  display: inline-block;
  padding: 5px 14px;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 15px;
}
.pager li > a:hover,
.pager li > a:focus {
  text-decoration: none;
  background-color: #eeeeee;
}
.pager .next > a,
.pager .next > span {
  float: right;
}
.pager .previous > a,
.pager .previous > span {
  float: left;
}
.pager .disabled > a,
.pager .disabled > a:hover,
.pager .disabled > a:focus,
.pager .disabled > span {
  color: #777777;
  background-color: #fff;
  cursor: not-allowed;
}
.label {
  display: inline;
  padding: .2em .6em .3em;
  font-size: 75%;
  font-weight: bold;
  line-height: 1;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: .25em;
}
a.label:hover,
a.label:focus {
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}
.label:empty {
  display: none;
}
.btn .label {
  position: relative;
  top: -1px;
}
.label-default {
  background-color: #777777;
}
.label-default[href]:hover,
.label-default[href]:focus {
  background-color: #5e5e5e;
}
.label-primary {
  background-color: #337ab7;
}
.label-primary[href]:hover,
.label-primary[href]:focus {
  background-color: #286090;
}
.label-success {
  background-color: #5cb85c;
}
.label-success[href]:hover,
.label-success[href]:focus {
  background-color: #449d44;
}
.label-info {
  background-color: #5bc0de;
}
.label-info[href]:hover,
.label-info[href]:focus {
  background-color: #31b0d5;
}
.label-warning {
  background-color: #f0ad4e;
}
.label-warning[href]:hover,
.label-warning[href]:focus {
  background-color: #ec971f;
}
.label-danger {
  background-color: #d9534f;
}
.label-danger[href]:hover,
.label-danger[href]:focus {
  background-color: #c9302c;
}
.badge {
  display: inline-block;
  min-width: 10px;
  padding: 3px 7px;
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  line-height: 1;
  vertical-align: middle;
  white-space: nowrap;
  text-align: center;
  background-color: #777777;
  border-radius: 10px;
}
.badge:empty {
  display: none;
}
.btn .badge {
  position: relative;
  top: -1px;
}
.btn-xs .badge,
.btn-group-xs > .btn .badge {
  top: 0;
  padding: 1px 5px;
}
a.badge:hover,
a.badge:focus {
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}
.list-group-item.active > .badge,
.nav-pills > .active > a > .badge {
  color: #337ab7;
  background-color: #fff;
}
.list-group-item > .badge {
  float: right;
}
.list-group-item > .badge + .badge {
  margin-right: 5px;
}
.nav-pills > li > a > .badge {
  margin-left: 3px;
}
.jumbotron {
  padding-top: 30px;
  padding-bottom: 30px;
  margin-bottom: 30px;
  color: inherit;
  background-color: #eeeeee;
}
.jumbotron h1,
.jumbotron .h1 {
  color: inherit;
}
.jumbotron p {
  margin-bottom: 15px;
  font-size: 20px;
  font-weight: 200;
}
.jumbotron > hr {
  border-top-color: #d5d5d5;
}
.container .jumbotron,
.container-fluid .jumbotron {
  border-radius: 3px;
  padding-left: 0px;
  padding-right: 0px;
}
.jumbotron .container {
  max-width: 100%;
}
@media screen and (min-width: 768px) {
  .jumbotron {
    padding-top: 48px;
    padding-bottom: 48px;
  }
  .container .jumbotron,
  .container-fluid .jumbotron {
    padding-left: 60px;
    padding-right: 60px;
  }
  .jumbotron h1,
  .jumbotron .h1 {
    font-size: 59px;
  }
}
.thumbnail {
  display: block;
  padding: 4px;
  margin-bottom: 18px;
  line-height: 1.42857143;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 2px;
  -webkit-transition: border 0.2s ease-in-out;
  -o-transition: border 0.2s ease-in-out;
  transition: border 0.2s ease-in-out;
}
.thumbnail > img,
.thumbnail a > img {
  margin-left: auto;
  margin-right: auto;
}
a.thumbnail:hover,
a.thumbnail:focus,
a.thumbnail.active {
  border-color: #337ab7;
}
.thumbnail .caption {
  padding: 9px;
  color: #000;
}
.alert {
  padding: 15px;
  margin-bottom: 18px;
  border: 1px solid transparent;
  border-radius: 2px;
}
.alert h4 {
  margin-top: 0;
  color: inherit;
}
.alert .alert-link {
  font-weight: bold;
}
.alert > p,
.alert > ul {
  margin-bottom: 0;
}
.alert > p + p {
  margin-top: 5px;
}
.alert-dismissable,
.alert-dismissible {
  padding-right: 35px;
}
.alert-dismissable .close,
.alert-dismissible .close {
  position: relative;
  top: -2px;
  right: -21px;
  color: inherit;
}
.alert-success {
  background-color: #dff0d8;
  border-color: #d6e9c6;
  color: #3c763d;
}
.alert-success hr {
  border-top-color: #c9e2b3;
}
.alert-success .alert-link {
  color: #2b542c;
}
.alert-info {
  background-color: #d9edf7;
  border-color: #bce8f1;
  color: #31708f;
}
.alert-info hr {
  border-top-color: #a6e1ec;
}
.alert-info .alert-link {
  color: #245269;
}
.alert-warning {
  background-color: #fcf8e3;
  border-color: #faebcc;
  color: #8a6d3b;
}
.alert-warning hr {
  border-top-color: #f7e1b5;
}
.alert-warning .alert-link {
  color: #66512c;
}
.alert-danger {
  background-color: #f2dede;
  border-color: #ebccd1;
  color: #a94442;
}
.alert-danger hr {
  border-top-color: #e4b9c0;
}
.alert-danger .alert-link {
  color: #843534;
}
@-webkit-keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}
@keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}
.progress {
  overflow: hidden;
  height: 18px;
  margin-bottom: 18px;
  background-color: #f5f5f5;
  border-radius: 2px;
  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar {
  float: left;
  width: 0%;
  height: 100%;
  font-size: 12px;
  line-height: 18px;
  color: #fff;
  text-align: center;
  background-color: #337ab7;
  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
  -webkit-transition: width 0.6s ease;
  -o-transition: width 0.6s ease;
  transition: width 0.6s ease;
}
.progress-striped .progress-bar,
.progress-bar-striped {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-size: 40px 40px;
}
.progress.active .progress-bar,
.progress-bar.active {
  -webkit-animation: progress-bar-stripes 2s linear infinite;
  -o-animation: progress-bar-stripes 2s linear infinite;
  animation: progress-bar-stripes 2s linear infinite;
}
.progress-bar-success {
  background-color: #5cb85c;
}
.progress-striped .progress-bar-success {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.progress-bar-info {
  background-color: #5bc0de;
}
.progress-striped .progress-bar-info {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.progress-bar-warning {
  background-color: #f0ad4e;
}
.progress-striped .progress-bar-warning {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.progress-bar-danger {
  background-color: #d9534f;
}
.progress-striped .progress-bar-danger {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.media {
  margin-top: 15px;
}
.media:first-child {
  margin-top: 0;
}
.media,
.media-body {
  zoom: 1;
  overflow: hidden;
}
.media-body {
  width: 10000px;
}
.media-object {
  display: block;
}
.media-object.img-thumbnail {
  max-width: none;
}
.media-right,
.media > .pull-right {
  padding-left: 10px;
}
.media-left,
.media > .pull-left {
  padding-right: 10px;
}
.media-left,
.media-right,
.media-body {
  display: table-cell;
  vertical-align: top;
}
.media-middle {
  vertical-align: middle;
}
.media-bottom {
  vertical-align: bottom;
}
.media-heading {
  margin-top: 0;
  margin-bottom: 5px;
}
.media-list {
  padding-left: 0;
  list-style: none;
}
.list-group {
  margin-bottom: 20px;
  padding-left: 0;
}
.list-group-item {
  position: relative;
  display: block;
  padding: 10px 15px;
  margin-bottom: -1px;
  background-color: #fff;
  border: 1px solid #ddd;
}
.list-group-item:first-child {
  border-top-right-radius: 2px;
  border-top-left-radius: 2px;
}
.list-group-item:last-child {
  margin-bottom: 0;
  border-bottom-right-radius: 2px;
  border-bottom-left-radius: 2px;
}
a.list-group-item,
button.list-group-item {
  color: #555;
}
a.list-group-item .list-group-item-heading,
button.list-group-item .list-group-item-heading {
  color: #333;
}
a.list-group-item:hover,
button.list-group-item:hover,
a.list-group-item:focus,
button.list-group-item:focus {
  text-decoration: none;
  color: #555;
  background-color: #f5f5f5;
}
button.list-group-item {
  width: 100%;
  text-align: left;
}
.list-group-item.disabled,
.list-group-item.disabled:hover,
.list-group-item.disabled:focus {
  background-color: #eeeeee;
  color: #777777;
  cursor: not-allowed;
}
.list-group-item.disabled .list-group-item-heading,
.list-group-item.disabled:hover .list-group-item-heading,
.list-group-item.disabled:focus .list-group-item-heading {
  color: inherit;
}
.list-group-item.disabled .list-group-item-text,
.list-group-item.disabled:hover .list-group-item-text,
.list-group-item.disabled:focus .list-group-item-text {
  color: #777777;
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
  z-index: 2;
  color: #fff;
  background-color: #337ab7;
  border-color: #337ab7;
}
.list-group-item.active .list-group-item-heading,
.list-group-item.active:hover .list-group-item-heading,
.list-group-item.active:focus .list-group-item-heading,
.list-group-item.active .list-group-item-heading > small,
.list-group-item.active:hover .list-group-item-heading > small,
.list-group-item.active:focus .list-group-item-heading > small,
.list-group-item.active .list-group-item-heading > .small,
.list-group-item.active:hover .list-group-item-heading > .small,
.list-group-item.active:focus .list-group-item-heading > .small {
  color: inherit;
}
.list-group-item.active .list-group-item-text,
.list-group-item.active:hover .list-group-item-text,
.list-group-item.active:focus .list-group-item-text {
  color: #c7ddef;
}
.list-group-item-success {
  color: #3c763d;
  background-color: #dff0d8;
}
a.list-group-item-success,
button.list-group-item-success {
  color: #3c763d;
}
a.list-group-item-success .list-group-item-heading,
button.list-group-item-success .list-group-item-heading {
  color: inherit;
}
a.list-group-item-success:hover,
button.list-group-item-success:hover,
a.list-group-item-success:focus,
button.list-group-item-success:focus {
  color: #3c763d;
  background-color: #d0e9c6;
}
a.list-group-item-success.active,
button.list-group-item-success.active,
a.list-group-item-success.active:hover,
button.list-group-item-success.active:hover,
a.list-group-item-success.active:focus,
button.list-group-item-success.active:focus {
  color: #fff;
  background-color: #3c763d;
  border-color: #3c763d;
}
.list-group-item-info {
  color: #31708f;
  background-color: #d9edf7;
}
a.list-group-item-info,
button.list-group-item-info {
  color: #31708f;
}
a.list-group-item-info .list-group-item-heading,
button.list-group-item-info .list-group-item-heading {
  color: inherit;
}
a.list-group-item-info:hover,
button.list-group-item-info:hover,
a.list-group-item-info:focus,
button.list-group-item-info:focus {
  color: #31708f;
  background-color: #c4e3f3;
}
a.list-group-item-info.active,
button.list-group-item-info.active,
a.list-group-item-info.active:hover,
button.list-group-item-info.active:hover,
a.list-group-item-info.active:focus,
button.list-group-item-info.active:focus {
  color: #fff;
  background-color: #31708f;
  border-color: #31708f;
}
.list-group-item-warning {
  color: #8a6d3b;
  background-color: #fcf8e3;
}
a.list-group-item-warning,
button.list-group-item-warning {
  color: #8a6d3b;
}
a.list-group-item-warning .list-group-item-heading,
button.list-group-item-warning .list-group-item-heading {
  color: inherit;
}
a.list-group-item-warning:hover,
button.list-group-item-warning:hover,
a.list-group-item-warning:focus,
button.list-group-item-warning:focus {
  color: #8a6d3b;
  background-color: #faf2cc;
}
a.list-group-item-warning.active,
button.list-group-item-warning.active,
a.list-group-item-warning.active:hover,
button.list-group-item-warning.active:hover,
a.list-group-item-warning.active:focus,
button.list-group-item-warning.active:focus {
  color: #fff;
  background-color: #8a6d3b;
  border-color: #8a6d3b;
}
.list-group-item-danger {
  color: #a94442;
  background-color: #f2dede;
}
a.list-group-item-danger,
button.list-group-item-danger {
  color: #a94442;
}
a.list-group-item-danger .list-group-item-heading,
button.list-group-item-danger .list-group-item-heading {
  color: inherit;
}
a.list-group-item-danger:hover,
button.list-group-item-danger:hover,
a.list-group-item-danger:focus,
button.list-group-item-danger:focus {
  color: #a94442;
  background-color: #ebcccc;
}
a.list-group-item-danger.active,
button.list-group-item-danger.active,
a.list-group-item-danger.active:hover,
button.list-group-item-danger.active:hover,
a.list-group-item-danger.active:focus,
button.list-group-item-danger.active:focus {
  color: #fff;
  background-color: #a94442;
  border-color: #a94442;
}
.list-group-item-heading {
  margin-top: 0;
  margin-bottom: 5px;
}
.list-group-item-text {
  margin-bottom: 0;
  line-height: 1.3;
}
.panel {
  margin-bottom: 18px;
  background-color: #fff;
  border: 1px solid transparent;
  border-radius: 2px;
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
.panel-body {
  padding: 15px;
}
.panel-heading {
  padding: 10px 15px;
  border-bottom: 1px solid transparent;
  border-top-right-radius: 1px;
  border-top-left-radius: 1px;
}
.panel-heading > .dropdown .dropdown-toggle {
  color: inherit;
}
.panel-title {
  margin-top: 0;
  margin-bottom: 0;
  font-size: 15px;
  color: inherit;
}
.panel-title > a,
.panel-title > small,
.panel-title > .small,
.panel-title > small > a,
.panel-title > .small > a {
  color: inherit;
}
.panel-footer {
  padding: 10px 15px;
  background-color: #f5f5f5;
  border-top: 1px solid #ddd;
  border-bottom-right-radius: 1px;
  border-bottom-left-radius: 1px;
}
.panel > .list-group,
.panel > .panel-collapse > .list-group {
  margin-bottom: 0;
}
.panel > .list-group .list-group-item,
.panel > .panel-collapse > .list-group .list-group-item {
  border-width: 1px 0;
  border-radius: 0;
}
.panel > .list-group:first-child .list-group-item:first-child,
.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
  border-top: 0;
  border-top-right-radius: 1px;
  border-top-left-radius: 1px;
}
.panel > .list-group:last-child .list-group-item:last-child,
.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
  border-bottom: 0;
  border-bottom-right-radius: 1px;
  border-bottom-left-radius: 1px;
}
.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}
.panel-heading + .list-group .list-group-item:first-child {
  border-top-width: 0;
}
.list-group + .panel-footer {
  border-top-width: 0;
}
.panel > .table,
.panel > .table-responsive > .table,
.panel > .panel-collapse > .table {
  margin-bottom: 0;
}
.panel > .table caption,
.panel > .table-responsive > .table caption,
.panel > .panel-collapse > .table caption {
  padding-left: 15px;
  padding-right: 15px;
}
.panel > .table:first-child,
.panel > .table-responsive:first-child > .table:first-child {
  border-top-right-radius: 1px;
  border-top-left-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
  border-top-left-radius: 1px;
  border-top-right-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
  border-top-left-radius: 1px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
  border-top-right-radius: 1px;
}
.panel > .table:last-child,
.panel > .table-responsive:last-child > .table:last-child {
  border-bottom-right-radius: 1px;
  border-bottom-left-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
  border-bottom-left-radius: 1px;
  border-bottom-right-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
  border-bottom-left-radius: 1px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
  border-bottom-right-radius: 1px;
}
.panel > .panel-body + .table,
.panel > .panel-body + .table-responsive,
.panel > .table + .panel-body,
.panel > .table-responsive + .panel-body {
  border-top: 1px solid #ddd;
}
.panel > .table > tbody:first-child > tr:first-child th,
.panel > .table > tbody:first-child > tr:first-child td {
  border-top: 0;
}
.panel > .table-bordered,
.panel > .table-responsive > .table-bordered {
  border: 0;
}
.panel > .table-bordered > thead > tr > th:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
.panel > .table-bordered > tbody > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
.panel > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-bordered > thead > tr > td:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
.panel > .table-bordered > tbody > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
.panel > .table-bordered > tfoot > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
  border-left: 0;
}
.panel > .table-bordered > thead > tr > th:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
.panel > .table-bordered > tbody > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
.panel > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-bordered > thead > tr > td:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
.panel > .table-bordered > tbody > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
.panel > .table-bordered > tfoot > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
  border-right: 0;
}
.panel > .table-bordered > thead > tr:first-child > td,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
.panel > .table-bordered > tbody > tr:first-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
.panel > .table-bordered > thead > tr:first-child > th,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
.panel > .table-bordered > tbody > tr:first-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
  border-bottom: 0;
}
.panel > .table-bordered > tbody > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
.panel > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-bordered > tbody > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
.panel > .table-bordered > tfoot > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
  border-bottom: 0;
}
.panel > .table-responsive {
  border: 0;
  margin-bottom: 0;
}
.panel-group {
  margin-bottom: 18px;
}
.panel-group .panel {
  margin-bottom: 0;
  border-radius: 2px;
}
.panel-group .panel + .panel {
  margin-top: 5px;
}
.panel-group .panel-heading {
  border-bottom: 0;
}
.panel-group .panel-heading + .panel-collapse > .panel-body,
.panel-group .panel-heading + .panel-collapse > .list-group {
  border-top: 1px solid #ddd;
}
.panel-group .panel-footer {
  border-top: 0;
}
.panel-group .panel-footer + .panel-collapse .panel-body {
  border-bottom: 1px solid #ddd;
}
.panel-default {
  border-color: #ddd;
}
.panel-default > .panel-heading {
  color: #333333;
  background-color: #f5f5f5;
  border-color: #ddd;
}
.panel-default > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #ddd;
}
.panel-default > .panel-heading .badge {
  color: #f5f5f5;
  background-color: #333333;
}
.panel-default > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #ddd;
}
.panel-primary {
  border-color: #337ab7;
}
.panel-primary > .panel-heading {
  color: #fff;
  background-color: #337ab7;
  border-color: #337ab7;
}
.panel-primary > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #337ab7;
}
.panel-primary > .panel-heading .badge {
  color: #337ab7;
  background-color: #fff;
}
.panel-primary > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #337ab7;
}
.panel-success {
  border-color: #d6e9c6;
}
.panel-success > .panel-heading {
  color: #3c763d;
  background-color: #dff0d8;
  border-color: #d6e9c6;
}
.panel-success > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #d6e9c6;
}
.panel-success > .panel-heading .badge {
  color: #dff0d8;
  background-color: #3c763d;
}
.panel-success > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #d6e9c6;
}
.panel-info {
  border-color: #bce8f1;
}
.panel-info > .panel-heading {
  color: #31708f;
  background-color: #d9edf7;
  border-color: #bce8f1;
}
.panel-info > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #bce8f1;
}
.panel-info > .panel-heading .badge {
  color: #d9edf7;
  background-color: #31708f;
}
.panel-info > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #bce8f1;
}
.panel-warning {
  border-color: #faebcc;
}
.panel-warning > .panel-heading {
  color: #8a6d3b;
  background-color: #fcf8e3;
  border-color: #faebcc;
}
.panel-warning > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #faebcc;
}
.panel-warning > .panel-heading .badge {
  color: #fcf8e3;
  background-color: #8a6d3b;
}
.panel-warning > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #faebcc;
}
.panel-danger {
  border-color: #ebccd1;
}
.panel-danger > .panel-heading {
  color: #a94442;
  background-color: #f2dede;
  border-color: #ebccd1;
}
.panel-danger > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #ebccd1;
}
.panel-danger > .panel-heading .badge {
  color: #f2dede;
  background-color: #a94442;
}
.panel-danger > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #ebccd1;
}
.embed-responsive {
  position: relative;
  display: block;
  height: 0;
  padding: 0;
  overflow: hidden;
}
.embed-responsive .embed-responsive-item,
.embed-responsive iframe,
.embed-responsive embed,
.embed-responsive object,
.embed-responsive video {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  height: 100%;
  width: 100%;
  border: 0;
}
.embed-responsive-16by9 {
  padding-bottom: 56.25%;
}
.embed-responsive-4by3 {
  padding-bottom: 75%;
}
.well {
  min-height: 20px;
  padding: 19px;
  margin-bottom: 20px;
  background-color: #f5f5f5;
  border: 1px solid #e3e3e3;
  border-radius: 2px;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
}
.well blockquote {
  border-color: #ddd;
  border-color: rgba(0, 0, 0, 0.15);
}
.well-lg {
  padding: 24px;
  border-radius: 3px;
}
.well-sm {
  padding: 9px;
  border-radius: 1px;
}
.close {
  float: right;
  font-size: 19.5px;
  font-weight: bold;
  line-height: 1;
  color: #000;
  text-shadow: 0 1px 0 #fff;
  opacity: 0.2;
  filter: alpha(opacity=20);
}
.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.5;
  filter: alpha(opacity=50);
}
button.close {
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
}
.modal-open {
  overflow: hidden;
}
.modal {
  display: none;
  overflow: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1050;
  -webkit-overflow-scrolling: touch;
  outline: 0;
}
.modal.fade .modal-dialog {
  -webkit-transform: translate(0, -25%);
  -ms-transform: translate(0, -25%);
  -o-transform: translate(0, -25%);
  transform: translate(0, -25%);
  -webkit-transition: -webkit-transform 0.3s ease-out;
  -moz-transition: -moz-transform 0.3s ease-out;
  -o-transition: -o-transform 0.3s ease-out;
  transition: transform 0.3s ease-out;
}
.modal.in .modal-dialog {
  -webkit-transform: translate(0, 0);
  -ms-transform: translate(0, 0);
  -o-transform: translate(0, 0);
  transform: translate(0, 0);
}
.modal-open .modal {
  overflow-x: hidden;
  overflow-y: auto;
}
.modal-dialog {
  position: relative;
  width: auto;
  margin: 10px;
}
.modal-content {
  position: relative;
  background-color: #fff;
  border: 1px solid #999;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
  background-clip: padding-box;
  outline: 0;
}
.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040;
  background-color: #000;
}
.modal-backdrop.fade {
  opacity: 0;
  filter: alpha(opacity=0);
}
.modal-backdrop.in {
  opacity: 0.5;
  filter: alpha(opacity=50);
}
.modal-header {
  padding: 15px;
  border-bottom: 1px solid #e5e5e5;
}
.modal-header .close {
  margin-top: -2px;
}
.modal-title {
  margin: 0;
  line-height: 1.42857143;
}
.modal-body {
  position: relative;
  padding: 15px;
}
.modal-footer {
  padding: 15px;
  text-align: right;
  border-top: 1px solid #e5e5e5;
}
.modal-footer .btn + .btn {
  margin-left: 5px;
  margin-bottom: 0;
}
.modal-footer .btn-group .btn + .btn {
  margin-left: -1px;
}
.modal-footer .btn-block + .btn-block {
  margin-left: 0;
}
.modal-scrollbar-measure {
  position: absolute;
  top: -9999px;
  width: 50px;
  height: 50px;
  overflow: scroll;
}
@media (min-width: 768px) {
  .modal-dialog {
    width: 600px;
    margin: 30px auto;
  }
  .modal-content {
    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
  }
  .modal-sm {
    width: 300px;
  }
}
@media (min-width: 992px) {
  .modal-lg {
    width: 900px;
  }
}
.tooltip {
  position: absolute;
  z-index: 1070;
  display: block;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-style: normal;
  font-weight: normal;
  letter-spacing: normal;
  line-break: auto;
  line-height: 1.42857143;
  text-align: left;
  text-align: start;
  text-decoration: none;
  text-shadow: none;
  text-transform: none;
  white-space: normal;
  word-break: normal;
  word-spacing: normal;
  word-wrap: normal;
  font-size: 12px;
  opacity: 0;
  filter: alpha(opacity=0);
}
.tooltip.in {
  opacity: 0.9;
  filter: alpha(opacity=90);
}
.tooltip.top {
  margin-top: -3px;
  padding: 5px 0;
}
.tooltip.right {
  margin-left: 3px;
  padding: 0 5px;
}
.tooltip.bottom {
  margin-top: 3px;
  padding: 5px 0;
}
.tooltip.left {
  margin-left: -3px;
  padding: 0 5px;
}
.tooltip-inner {
  max-width: 200px;
  padding: 3px 8px;
  color: #fff;
  text-align: center;
  background-color: #000;
  border-radius: 2px;
}
.tooltip-arrow {
  position: absolute;
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
}
.tooltip.top .tooltip-arrow {
  bottom: 0;
  left: 50%;
  margin-left: -5px;
  border-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.top-left .tooltip-arrow {
  bottom: 0;
  right: 5px;
  margin-bottom: -5px;
  border-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.top-right .tooltip-arrow {
  bottom: 0;
  left: 5px;
  margin-bottom: -5px;
  border-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.right .tooltip-arrow {
  top: 50%;
  left: 0;
  margin-top: -5px;
  border-width: 5px 5px 5px 0;
  border-right-color: #000;
}
.tooltip.left .tooltip-arrow {
  top: 50%;
  right: 0;
  margin-top: -5px;
  border-width: 5px 0 5px 5px;
  border-left-color: #000;
}
.tooltip.bottom .tooltip-arrow {
  top: 0;
  left: 50%;
  margin-left: -5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}
.tooltip.bottom-left .tooltip-arrow {
  top: 0;
  right: 5px;
  margin-top: -5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}
.tooltip.bottom-right .tooltip-arrow {
  top: 0;
  left: 5px;
  margin-top: -5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}
.popover {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1060;
  display: none;
  max-width: 276px;
  padding: 1px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-style: normal;
  font-weight: normal;
  letter-spacing: normal;
  line-break: auto;
  line-height: 1.42857143;
  text-align: left;
  text-align: start;
  text-decoration: none;
  text-shadow: none;
  text-transform: none;
  white-space: normal;
  word-break: normal;
  word-spacing: normal;
  word-wrap: normal;
  font-size: 13px;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.popover.top {
  margin-top: -10px;
}
.popover.right {
  margin-left: 10px;
}
.popover.bottom {
  margin-top: 10px;
}
.popover.left {
  margin-left: -10px;
}
.popover-title {
  margin: 0;
  padding: 8px 14px;
  font-size: 13px;
  background-color: #f7f7f7;
  border-bottom: 1px solid #ebebeb;
  border-radius: 2px 2px 0 0;
}
.popover-content {
  padding: 9px 14px;
}
.popover > .arrow,
.popover > .arrow:after {
  position: absolute;
  display: block;
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
}
.popover > .arrow {
  border-width: 11px;
}
.popover > .arrow:after {
  border-width: 10px;
  content: "";
}
.popover.top > .arrow {
  left: 50%;
  margin-left: -11px;
  border-bottom-width: 0;
  border-top-color: #999999;
  border-top-color: rgba(0, 0, 0, 0.25);
  bottom: -11px;
}
.popover.top > .arrow:after {
  content: " ";
  bottom: 1px;
  margin-left: -10px;
  border-bottom-width: 0;
  border-top-color: #fff;
}
.popover.right > .arrow {
  top: 50%;
  left: -11px;
  margin-top: -11px;
  border-left-width: 0;
  border-right-color: #999999;
  border-right-color: rgba(0, 0, 0, 0.25);
}
.popover.right > .arrow:after {
  content: " ";
  left: 1px;
  bottom: -10px;
  border-left-width: 0;
  border-right-color: #fff;
}
.popover.bottom > .arrow {
  left: 50%;
  margin-left: -11px;
  border-top-width: 0;
  border-bottom-color: #999999;
  border-bottom-color: rgba(0, 0, 0, 0.25);
  top: -11px;
}
.popover.bottom > .arrow:after {
  content: " ";
  top: 1px;
  margin-left: -10px;
  border-top-width: 0;
  border-bottom-color: #fff;
}
.popover.left > .arrow {
  top: 50%;
  right: -11px;
  margin-top: -11px;
  border-right-width: 0;
  border-left-color: #999999;
  border-left-color: rgba(0, 0, 0, 0.25);
}
.popover.left > .arrow:after {
  content: " ";
  right: 1px;
  border-right-width: 0;
  border-left-color: #fff;
  bottom: -10px;
}
.carousel {
  position: relative;
}
.carousel-inner {
  position: relative;
  overflow: hidden;
  width: 100%;
}
.carousel-inner > .item {
  display: none;
  position: relative;
  -webkit-transition: 0.6s ease-in-out left;
  -o-transition: 0.6s ease-in-out left;
  transition: 0.6s ease-in-out left;
}
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
  line-height: 1;
}
@media all and (transform-3d), (-webkit-transform-3d) {
  .carousel-inner > .item {
    -webkit-transition: -webkit-transform 0.6s ease-in-out;
    -moz-transition: -moz-transform 0.6s ease-in-out;
    -o-transition: -o-transform 0.6s ease-in-out;
    transition: transform 0.6s ease-in-out;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    backface-visibility: hidden;
    -webkit-perspective: 1000px;
    -moz-perspective: 1000px;
    perspective: 1000px;
  }
  .carousel-inner > .item.next,
  .carousel-inner > .item.active.right {
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
    left: 0;
  }
  .carousel-inner > .item.prev,
  .carousel-inner > .item.active.left {
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
    left: 0;
  }
  .carousel-inner > .item.next.left,
  .carousel-inner > .item.prev.right,
  .carousel-inner > .item.active {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    left: 0;
  }
}
.carousel-inner > .active,
.carousel-inner > .next,
.carousel-inner > .prev {
  display: block;
}
.carousel-inner > .active {
  left: 0;
}
.carousel-inner > .next,
.carousel-inner > .prev {
  position: absolute;
  top: 0;
  width: 100%;
}
.carousel-inner > .next {
  left: 100%;
}
.carousel-inner > .prev {
  left: -100%;
}
.carousel-inner > .next.left,
.carousel-inner > .prev.right {
  left: 0;
}
.carousel-inner > .active.left {
  left: -100%;
}
.carousel-inner > .active.right {
  left: 100%;
}
.carousel-control {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 15%;
  opacity: 0.5;
  filter: alpha(opacity=50);
  font-size: 20px;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  background-color: rgba(0, 0, 0, 0);
}
.carousel-control.left {
  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
}
.carousel-control.right {
  left: auto;
  right: 0;
  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
}
.carousel-control:hover,
.carousel-control:focus {
  outline: 0;
  color: #fff;
  text-decoration: none;
  opacity: 0.9;
  filter: alpha(opacity=90);
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
  position: absolute;
  top: 50%;
  margin-top: -10px;
  z-index: 5;
  display: inline-block;
}
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
  left: 50%;
  margin-left: -10px;
}
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-right {
  right: 50%;
  margin-right: -10px;
}
.carousel-control .icon-prev,
.carousel-control .icon-next {
  width: 20px;
  height: 20px;
  line-height: 1;
  font-family: serif;
}
.carousel-control .icon-prev:before {
  content: '\2039';
}
.carousel-control .icon-next:before {
  content: '\203a';
}
.carousel-indicators {
  position: absolute;
  bottom: 10px;
  left: 50%;
  z-index: 15;
  width: 60%;
  margin-left: -30%;
  padding-left: 0;
  list-style: none;
  text-align: center;
}
.carousel-indicators li {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin: 1px;
  text-indent: -999px;
  border: 1px solid #fff;
  border-radius: 10px;
  cursor: pointer;
  background-color: #000 \9;
  background-color: rgba(0, 0, 0, 0);
}
.carousel-indicators .active {
  margin: 0;
  width: 12px;
  height: 12px;
  background-color: #fff;
}
.carousel-caption {
  position: absolute;
  left: 15%;
  right: 15%;
  bottom: 20px;
  z-index: 10;
  padding-top: 20px;
  padding-bottom: 20px;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.carousel-caption .btn {
  text-shadow: none;
}
@media screen and (min-width: 768px) {
  .carousel-control .glyphicon-chevron-left,
  .carousel-control .glyphicon-chevron-right,
  .carousel-control .icon-prev,
  .carousel-control .icon-next {
    width: 30px;
    height: 30px;
    margin-top: -10px;
    font-size: 30px;
  }
  .carousel-control .glyphicon-chevron-left,
  .carousel-control .icon-prev {
    margin-left: -10px;
  }
  .carousel-control .glyphicon-chevron-right,
  .carousel-control .icon-next {
    margin-right: -10px;
  }
  .carousel-caption {
    left: 20%;
    right: 20%;
    padding-bottom: 30px;
  }
  .carousel-indicators {
    bottom: 20px;
  }
}
.clearfix:before,
.clearfix:after,
.dl-horizontal dd:before,
.dl-horizontal dd:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after,
.form-horizontal .form-group:before,
.form-horizontal .form-group:after,
.btn-toolbar:before,
.btn-toolbar:after,
.btn-group-vertical > .btn-group:before,
.btn-group-vertical > .btn-group:after,
.nav:before,
.nav:after,
.navbar:before,
.navbar:after,
.navbar-header:before,
.navbar-header:after,
.navbar-collapse:before,
.navbar-collapse:after,
.pager:before,
.pager:after,
.panel-body:before,
.panel-body:after,
.modal-header:before,
.modal-header:after,
.modal-footer:before,
.modal-footer:after,
.item_buttons:before,
.item_buttons:after {
  content: " ";
  display: table;
}
.clearfix:after,
.dl-horizontal dd:after,
.container:after,
.container-fluid:after,
.row:after,
.form-horizontal .form-group:after,
.btn-toolbar:after,
.btn-group-vertical > .btn-group:after,
.nav:after,
.navbar:after,
.navbar-header:after,
.navbar-collapse:after,
.pager:after,
.panel-body:after,
.modal-header:after,
.modal-footer:after,
.item_buttons:after {
  clear: both;
}
.center-block {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
.pull-right {
  float: right !important;
}
.pull-left {
  float: left !important;
}
.hide {
  display: none !important;
}
.show {
  display: block !important;
}
.invisible {
  visibility: hidden;
}
.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}
.hidden {
  display: none !important;
}
.affix {
  position: fixed;
}
@-ms-viewport {
  width: device-width;
}
.visible-xs,
.visible-sm,
.visible-md,
.visible-lg {
  display: none !important;
}
.visible-xs-block,
.visible-xs-inline,
.visible-xs-inline-block,
.visible-sm-block,
.visible-sm-inline,
.visible-sm-inline-block,
.visible-md-block,
.visible-md-inline,
.visible-md-inline-block,
.visible-lg-block,
.visible-lg-inline,
.visible-lg-inline-block {
  display: none !important;
}
@media (max-width: 767px) {
  .visible-xs {
    display: block !important;
  }
  table.visible-xs {
    display: table !important;
  }
  tr.visible-xs {
    display: table-row !important;
  }
  th.visible-xs,
  td.visible-xs {
    display: table-cell !important;
  }
}
@media (max-width: 767px) {
  .visible-xs-block {
    display: block !important;
  }
}
@media (max-width: 767px) {
  .visible-xs-inline {
    display: inline !important;
  }
}
@media (max-width: 767px) {
  .visible-xs-inline-block {
    display: inline-block !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm {
    display: block !important;
  }
  table.visible-sm {
    display: table !important;
  }
  tr.visible-sm {
    display: table-row !important;
  }
  th.visible-sm,
  td.visible-sm {
    display: table-cell !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-block {
    display: block !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-inline {
    display: inline !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-inline-block {
    display: inline-block !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md {
    display: block !important;
  }
  table.visible-md {
    display: table !important;
  }
  tr.visible-md {
    display: table-row !important;
  }
  th.visible-md,
  td.visible-md {
    display: table-cell !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-block {
    display: block !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-inline {
    display: inline !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-inline-block {
    display: inline-block !important;
  }
}
@media (min-width: 1200px) {
  .visible-lg {
    display: block !important;
  }
  table.visible-lg {
    display: table !important;
  }
  tr.visible-lg {
    display: table-row !important;
  }
  th.visible-lg,
  td.visible-lg {
    display: table-cell !important;
  }
}
@media (min-width: 1200px) {
  .visible-lg-block {
    display: block !important;
  }
}
@media (min-width: 1200px) {
  .visible-lg-inline {
    display: inline !important;
  }
}
@media (min-width: 1200px) {
  .visible-lg-inline-block {
    display: inline-block !important;
  }
}
@media (max-width: 767px) {
  .hidden-xs {
    display: none !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .hidden-sm {
    display: none !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .hidden-md {
    display: none !important;
  }
}
@media (min-width: 1200px) {
  .hidden-lg {
    display: none !important;
  }
}
.visible-print {
  display: none !important;
}
@media print {
  .visible-print {
    display: block !important;
  }
  table.visible-print {
    display: table !important;
  }
  tr.visible-print {
    display: table-row !important;
  }
  th.visible-print,
  td.visible-print {
    display: table-cell !important;
  }
}
.visible-print-block {
  display: none !important;
}
@media print {
  .visible-print-block {
    display: block !important;
  }
}
.visible-print-inline {
  display: none !important;
}
@media print {
  .visible-print-inline {
    display: inline !important;
  }
}
.visible-print-inline-block {
  display: none !important;
}
@media print {
  .visible-print-inline-block {
    display: inline-block !important;
  }
}
@media print {
  .hidden-print {
    display: none !important;
  }
}
/*!
*
* Font Awesome
*
*/
/*!
 *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
 *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
 */
/* FONT PATH
 * -------------------------- */
@font-face {
  font-family: 'FontAwesome';
  src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.2.0');
  src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../components/font-awesome/fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../components/font-awesome/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}
.fa {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* makes the font 33% larger relative to the icon container */
.fa-lg {
  font-size: 1.33333333em;
  line-height: 0.75em;
  vertical-align: -15%;
}
.fa-2x {
  font-size: 2em;
}
.fa-3x {
  font-size: 3em;
}
.fa-4x {
  font-size: 4em;
}
.fa-5x {
  font-size: 5em;
}
.fa-fw {
  width: 1.28571429em;
  text-align: center;
}
.fa-ul {
  padding-left: 0;
  margin-left: 2.14285714em;
  list-style-type: none;
}
.fa-ul > li {
  position: relative;
}
.fa-li {
  position: absolute;
  left: -2.14285714em;
  width: 2.14285714em;
  top: 0.14285714em;
  text-align: center;
}
.fa-li.fa-lg {
  left: -1.85714286em;
}
.fa-border {
  padding: .2em .25em .15em;
  border: solid 0.08em #eee;
  border-radius: .1em;
}
.pull-right {
  float: right;
}
.pull-left {
  float: left;
}
.fa.pull-left {
  margin-right: .3em;
}
.fa.pull-right {
  margin-left: .3em;
}
.fa-spin {
  -webkit-animation: fa-spin 2s infinite linear;
  animation: fa-spin 2s infinite linear;
}
@-webkit-keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
@keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
.fa-rotate-90 {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}
.fa-rotate-180 {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
  -webkit-transform: rotate(180deg);
  -ms-transform: rotate(180deg);
  transform: rotate(180deg);
}
.fa-rotate-270 {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
  -webkit-transform: rotate(270deg);
  -ms-transform: rotate(270deg);
  transform: rotate(270deg);
}
.fa-flip-horizontal {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
  -webkit-transform: scale(-1, 1);
  -ms-transform: scale(-1, 1);
  transform: scale(-1, 1);
}
.fa-flip-vertical {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
  -webkit-transform: scale(1, -1);
  -ms-transform: scale(1, -1);
  transform: scale(1, -1);
}
:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical {
  filter: none;
}
.fa-stack {
  position: relative;
  display: inline-block;
  width: 2em;
  height: 2em;
  line-height: 2em;
  vertical-align: middle;
}
.fa-stack-1x,
.fa-stack-2x {
  position: absolute;
  left: 0;
  width: 100%;
  text-align: center;
}
.fa-stack-1x {
  line-height: inherit;
}
.fa-stack-2x {
  font-size: 2em;
}
.fa-inverse {
  color: #fff;
}
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
   readers do not read off random characters that represent icons */
.fa-glass:before {
  content: "\f000";
}
.fa-music:before {
  content: "\f001";
}
.fa-search:before {
  content: "\f002";
}
.fa-envelope-o:before {
  content: "\f003";
}
.fa-heart:before {
  content: "\f004";
}
.fa-star:before {
  content: "\f005";
}
.fa-star-o:before {
  content: "\f006";
}
.fa-user:before {
  content: "\f007";
}
.fa-film:before {
  content: "\f008";
}
.fa-th-large:before {
  content: "\f009";
}
.fa-th:before {
  content: "\f00a";
}
.fa-th-list:before {
  content: "\f00b";
}
.fa-check:before {
  content: "\f00c";
}
.fa-remove:before,
.fa-close:before,
.fa-times:before {
  content: "\f00d";
}
.fa-search-plus:before {
  content: "\f00e";
}
.fa-search-minus:before {
  content: "\f010";
}
.fa-power-off:before {
  content: "\f011";
}
.fa-signal:before {
  content: "\f012";
}
.fa-gear:before,
.fa-cog:before {
  content: "\f013";
}
.fa-trash-o:before {
  content: "\f014";
}
.fa-home:before {
  content: "\f015";
}
.fa-file-o:before {
  content: "\f016";
}
.fa-clock-o:before {
  content: "\f017";
}
.fa-road:before {
  content: "\f018";
}
.fa-download:before {
  content: "\f019";
}
.fa-arrow-circle-o-down:before {
  content: "\f01a";
}
.fa-arrow-circle-o-up:before {
  content: "\f01b";
}
.fa-inbox:before {
  content: "\f01c";
}
.fa-play-circle-o:before {
  content: "\f01d";
}
.fa-rotate-right:before,
.fa-repeat:before {
  content: "\f01e";
}
.fa-refresh:before {
  content: "\f021";
}
.fa-list-alt:before {
  content: "\f022";
}
.fa-lock:before {
  content: "\f023";
}
.fa-flag:before {
  content: "\f024";
}
.fa-headphones:before {
  content: "\f025";
}
.fa-volume-off:before {
  content: "\f026";
}
.fa-volume-down:before {
  content: "\f027";
}
.fa-volume-up:before {
  content: "\f028";
}
.fa-qrcode:before {
  content: "\f029";
}
.fa-barcode:before {
  content: "\f02a";
}
.fa-tag:before {
  content: "\f02b";
}
.fa-tags:before {
  content: "\f02c";
}
.fa-book:before {
  content: "\f02d";
}
.fa-bookmark:before {
  content: "\f02e";
}
.fa-print:before {
  content: "\f02f";
}
.fa-camera:before {
  content: "\f030";
}
.fa-font:before {
  content: "\f031";
}
.fa-bold:before {
  content: "\f032";
}
.fa-italic:before {
  content: "\f033";
}
.fa-text-height:before {
  content: "\f034";
}
.fa-text-width:before {
  content: "\f035";
}
.fa-align-left:before {
  content: "\f036";
}
.fa-align-center:before {
  content: "\f037";
}
.fa-align-right:before {
  content: "\f038";
}
.fa-align-justify:before {
  content: "\f039";
}
.fa-list:before {
  content: "\f03a";
}
.fa-dedent:before,
.fa-outdent:before {
  content: "\f03b";
}
.fa-indent:before {
  content: "\f03c";
}
.fa-video-camera:before {
  content: "\f03d";
}
.fa-photo:before,
.fa-image:before,
.fa-picture-o:before {
  content: "\f03e";
}
.fa-pencil:before {
  content: "\f040";
}
.fa-map-marker:before {
  content: "\f041";
}
.fa-adjust:before {
  content: "\f042";
}
.fa-tint:before {
  content: "\f043";
}
.fa-edit:before,
.fa-pencil-square-o:before {
  content: "\f044";
}
.fa-share-square-o:before {
  content: "\f045";
}
.fa-check-square-o:before {
  content: "\f046";
}
.fa-arrows:before {
  content: "\f047";
}
.fa-step-backward:before {
  content: "\f048";
}
.fa-fast-backward:before {
  content: "\f049";
}
.fa-backward:before {
  content: "\f04a";
}
.fa-play:before {
  content: "\f04b";
}
.fa-pause:before {
  content: "\f04c";
}
.fa-stop:before {
  content: "\f04d";
}
.fa-forward:before {
  content: "\f04e";
}
.fa-fast-forward:before {
  content: "\f050";
}
.fa-step-forward:before {
  content: "\f051";
}
.fa-eject:before {
  content: "\f052";
}
.fa-chevron-left:before {
  content: "\f053";
}
.fa-chevron-right:before {
  content: "\f054";
}
.fa-plus-circle:before {
  content: "\f055";
}
.fa-minus-circle:before {
  content: "\f056";
}
.fa-times-circle:before {
  content: "\f057";
}
.fa-check-circle:before {
  content: "\f058";
}
.fa-question-circle:before {
  content: "\f059";
}
.fa-info-circle:before {
  content: "\f05a";
}
.fa-crosshairs:before {
  content: "\f05b";
}
.fa-times-circle-o:before {
  content: "\f05c";
}
.fa-check-circle-o:before {
  content: "\f05d";
}
.fa-ban:before {
  content: "\f05e";
}
.fa-arrow-left:before {
  content: "\f060";
}
.fa-arrow-right:before {
  content: "\f061";
}
.fa-arrow-up:before {
  content: "\f062";
}
.fa-arrow-down:before {
  content: "\f063";
}
.fa-mail-forward:before,
.fa-share:before {
  content: "\f064";
}
.fa-expand:before {
  content: "\f065";
}
.fa-compress:before {
  content: "\f066";
}
.fa-plus:before {
  content: "\f067";
}
.fa-minus:before {
  content: "\f068";
}
.fa-asterisk:before {
  content: "\f069";
}
.fa-exclamation-circle:before {
  content: "\f06a";
}
.fa-gift:before {
  content: "\f06b";
}
.fa-leaf:before {
  content: "\f06c";
}
.fa-fire:before {
  content: "\f06d";
}
.fa-eye:before {
  content: "\f06e";
}
.fa-eye-slash:before {
  content: "\f070";
}
.fa-warning:before,
.fa-exclamation-triangle:before {
  content: "\f071";
}
.fa-plane:before {
  content: "\f072";
}
.fa-calendar:before {
  content: "\f073";
}
.fa-random:before {
  content: "\f074";
}
.fa-comment:before {
  content: "\f075";
}
.fa-magnet:before {
  content: "\f076";
}
.fa-chevron-up:before {
  content: "\f077";
}
.fa-chevron-down:before {
  content: "\f078";
}
.fa-retweet:before {
  content: "\f079";
}
.fa-shopping-cart:before {
  content: "\f07a";
}
.fa-folder:before {
  content: "\f07b";
}
.fa-folder-open:before {
  content: "\f07c";
}
.fa-arrows-v:before {
  content: "\f07d";
}
.fa-arrows-h:before {
  content: "\f07e";
}
.fa-bar-chart-o:before,
.fa-bar-chart:before {
  content: "\f080";
}
.fa-twitter-square:before {
  content: "\f081";
}
.fa-facebook-square:before {
  content: "\f082";
}
.fa-camera-retro:before {
  content: "\f083";
}
.fa-key:before {
  content: "\f084";
}
.fa-gears:before,
.fa-cogs:before {
  content: "\f085";
}
.fa-comments:before {
  content: "\f086";
}
.fa-thumbs-o-up:before {
  content: "\f087";
}
.fa-thumbs-o-down:before {
  content: "\f088";
}
.fa-star-half:before {
  content: "\f089";
}
.fa-heart-o:before {
  content: "\f08a";
}
.fa-sign-out:before {
  content: "\f08b";
}
.fa-linkedin-square:before {
  content: "\f08c";
}
.fa-thumb-tack:before {
  content: "\f08d";
}
.fa-external-link:before {
  content: "\f08e";
}
.fa-sign-in:before {
  content: "\f090";
}
.fa-trophy:before {
  content: "\f091";
}
.fa-github-square:before {
  content: "\f092";
}
.fa-upload:before {
  content: "\f093";
}
.fa-lemon-o:before {
  content: "\f094";
}
.fa-phone:before {
  content: "\f095";
}
.fa-square-o:before {
  content: "\f096";
}
.fa-bookmark-o:before {
  content: "\f097";
}
.fa-phone-square:before {
  content: "\f098";
}
.fa-twitter:before {
  content: "\f099";
}
.fa-facebook:before {
  content: "\f09a";
}
.fa-github:before {
  content: "\f09b";
}
.fa-unlock:before {
  content: "\f09c";
}
.fa-credit-card:before {
  content: "\f09d";
}
.fa-rss:before {
  content: "\f09e";
}
.fa-hdd-o:before {
  content: "\f0a0";
}
.fa-bullhorn:before {
  content: "\f0a1";
}
.fa-bell:before {
  content: "\f0f3";
}
.fa-certificate:before {
  content: "\f0a3";
}
.fa-hand-o-right:before {
  content: "\f0a4";
}
.fa-hand-o-left:before {
  content: "\f0a5";
}
.fa-hand-o-up:before {
  content: "\f0a6";
}
.fa-hand-o-down:before {
  content: "\f0a7";
}
.fa-arrow-circle-left:before {
  content: "\f0a8";
}
.fa-arrow-circle-right:before {
  content: "\f0a9";
}
.fa-arrow-circle-up:before {
  content: "\f0aa";
}
.fa-arrow-circle-down:before {
  content: "\f0ab";
}
.fa-globe:before {
  content: "\f0ac";
}
.fa-wrench:before {
  content: "\f0ad";
}
.fa-tasks:before {
  content: "\f0ae";
}
.fa-filter:before {
  content: "\f0b0";
}
.fa-briefcase:before {
  content: "\f0b1";
}
.fa-arrows-alt:before {
  content: "\f0b2";
}
.fa-group:before,
.fa-users:before {
  content: "\f0c0";
}
.fa-chain:before,
.fa-link:before {
  content: "\f0c1";
}
.fa-cloud:before {
  content: "\f0c2";
}
.fa-flask:before {
  content: "\f0c3";
}
.fa-cut:before,
.fa-scissors:before {
  content: "\f0c4";
}
.fa-copy:before,
.fa-files-o:before {
  content: "\f0c5";
}
.fa-paperclip:before {
  content: "\f0c6";
}
.fa-save:before,
.fa-floppy-o:before {
  content: "\f0c7";
}
.fa-square:before {
  content: "\f0c8";
}
.fa-navicon:before,
.fa-reorder:before,
.fa-bars:before {
  content: "\f0c9";
}
.fa-list-ul:before {
  content: "\f0ca";
}
.fa-list-ol:before {
  content: "\f0cb";
}
.fa-strikethrough:before {
  content: "\f0cc";
}
.fa-underline:before {
  content: "\f0cd";
}
.fa-table:before {
  content: "\f0ce";
}
.fa-magic:before {
  content: "\f0d0";
}
.fa-truck:before {
  content: "\f0d1";
}
.fa-pinterest:before {
  content: "\f0d2";
}
.fa-pinterest-square:before {
  content: "\f0d3";
}
.fa-google-plus-square:before {
  content: "\f0d4";
}
.fa-google-plus:before {
  content: "\f0d5";
}
.fa-money:before {
  content: "\f0d6";
}
.fa-caret-down:before {
  content: "\f0d7";
}
.fa-caret-up:before {
  content: "\f0d8";
}
.fa-caret-left:before {
  content: "\f0d9";
}
.fa-caret-right:before {
  content: "\f0da";
}
.fa-columns:before {
  content: "\f0db";
}
.fa-unsorted:before,
.fa-sort:before {
  content: "\f0dc";
}
.fa-sort-down:before,
.fa-sort-desc:before {
  content: "\f0dd";
}
.fa-sort-up:before,
.fa-sort-asc:before {
  content: "\f0de";
}
.fa-envelope:before {
  content: "\f0e0";
}
.fa-linkedin:before {
  content: "\f0e1";
}
.fa-rotate-left:before,
.fa-undo:before {
  content: "\f0e2";
}
.fa-legal:before,
.fa-gavel:before {
  content: "\f0e3";
}
.fa-dashboard:before,
.fa-tachometer:before {
  content: "\f0e4";
}
.fa-comment-o:before {
  content: "\f0e5";
}
.fa-comments-o:before {
  content: "\f0e6";
}
.fa-flash:before,
.fa-bolt:before {
  content: "\f0e7";
}
.fa-sitemap:before {
  content: "\f0e8";
}
.fa-umbrella:before {
  content: "\f0e9";
}
.fa-paste:before,
.fa-clipboard:before {
  content: "\f0ea";
}
.fa-lightbulb-o:before {
  content: "\f0eb";
}
.fa-exchange:before {
  content: "\f0ec";
}
.fa-cloud-download:before {
  content: "\f0ed";
}
.fa-cloud-upload:before {
  content: "\f0ee";
}
.fa-user-md:before {
  content: "\f0f0";
}
.fa-stethoscope:before {
  content: "\f0f1";
}
.fa-suitcase:before {
  content: "\f0f2";
}
.fa-bell-o:before {
  content: "\f0a2";
}
.fa-coffee:before {
  content: "\f0f4";
}
.fa-cutlery:before {
  content: "\f0f5";
}
.fa-file-text-o:before {
  content: "\f0f6";
}
.fa-building-o:before {
  content: "\f0f7";
}
.fa-hospital-o:before {
  content: "\f0f8";
}
.fa-ambulance:before {
  content: "\f0f9";
}
.fa-medkit:before {
  content: "\f0fa";
}
.fa-fighter-jet:before {
  content: "\f0fb";
}
.fa-beer:before {
  content: "\f0fc";
}
.fa-h-square:before {
  content: "\f0fd";
}
.fa-plus-square:before {
  content: "\f0fe";
}
.fa-angle-double-left:before {
  content: "\f100";
}
.fa-angle-double-right:before {
  content: "\f101";
}
.fa-angle-double-up:before {
  content: "\f102";
}
.fa-angle-double-down:before {
  content: "\f103";
}
.fa-angle-left:before {
  content: "\f104";
}
.fa-angle-right:before {
  content: "\f105";
}
.fa-angle-up:before {
  content: "\f106";
}
.fa-angle-down:before {
  content: "\f107";
}
.fa-desktop:before {
  content: "\f108";
}
.fa-laptop:before {
  content: "\f109";
}
.fa-tablet:before {
  content: "\f10a";
}
.fa-mobile-phone:before,
.fa-mobile:before {
  content: "\f10b";
}
.fa-circle-o:before {
  content: "\f10c";
}
.fa-quote-left:before {
  content: "\f10d";
}
.fa-quote-right:before {
  content: "\f10e";
}
.fa-spinner:before {
  content: "\f110";
}
.fa-circle:before {
  content: "\f111";
}
.fa-mail-reply:before,
.fa-reply:before {
  content: "\f112";
}
.fa-github-alt:before {
  content: "\f113";
}
.fa-folder-o:before {
  content: "\f114";
}
.fa-folder-open-o:before {
  content: "\f115";
}
.fa-smile-o:before {
  content: "\f118";
}
.fa-frown-o:before {
  content: "\f119";
}
.fa-meh-o:before {
  content: "\f11a";
}
.fa-gamepad:before {
  content: "\f11b";
}
.fa-keyboard-o:before {
  content: "\f11c";
}
.fa-flag-o:before {
  content: "\f11d";
}
.fa-flag-checkered:before {
  content: "\f11e";
}
.fa-terminal:before {
  content: "\f120";
}
.fa-code:before {
  content: "\f121";
}
.fa-mail-reply-all:before,
.fa-reply-all:before {
  content: "\f122";
}
.fa-star-half-empty:before,
.fa-star-half-full:before,
.fa-star-half-o:before {
  content: "\f123";
}
.fa-location-arrow:before {
  content: "\f124";
}
.fa-crop:before {
  content: "\f125";
}
.fa-code-fork:before {
  content: "\f126";
}
.fa-unlink:before,
.fa-chain-broken:before {
  content: "\f127";
}
.fa-question:before {
  content: "\f128";
}
.fa-info:before {
  content: "\f129";
}
.fa-exclamation:before {
  content: "\f12a";
}
.fa-superscript:before {
  content: "\f12b";
}
.fa-subscript:before {
  content: "\f12c";
}
.fa-eraser:before {
  content: "\f12d";
}
.fa-puzzle-piece:before {
  content: "\f12e";
}
.fa-microphone:before {
  content: "\f130";
}
.fa-microphone-slash:before {
  content: "\f131";
}
.fa-shield:before {
  content: "\f132";
}
.fa-calendar-o:before {
  content: "\f133";
}
.fa-fire-extinguisher:before {
  content: "\f134";
}
.fa-rocket:before {
  content: "\f135";
}
.fa-maxcdn:before {
  content: "\f136";
}
.fa-chevron-circle-left:before {
  content: "\f137";
}
.fa-chevron-circle-right:before {
  content: "\f138";
}
.fa-chevron-circle-up:before {
  content: "\f139";
}
.fa-chevron-circle-down:before {
  content: "\f13a";
}
.fa-html5:before {
  content: "\f13b";
}
.fa-css3:before {
  content: "\f13c";
}
.fa-anchor:before {
  content: "\f13d";
}
.fa-unlock-alt:before {
  content: "\f13e";
}
.fa-bullseye:before {
  content: "\f140";
}
.fa-ellipsis-h:before {
  content: "\f141";
}
.fa-ellipsis-v:before {
  content: "\f142";
}
.fa-rss-square:before {
  content: "\f143";
}
.fa-play-circle:before {
  content: "\f144";
}
.fa-ticket:before {
  content: "\f145";
}
.fa-minus-square:before {
  content: "\f146";
}
.fa-minus-square-o:before {
  content: "\f147";
}
.fa-level-up:before {
  content: "\f148";
}
.fa-level-down:before {
  content: "\f149";
}
.fa-check-square:before {
  content: "\f14a";
}
.fa-pencil-square:before {
  content: "\f14b";
}
.fa-external-link-square:before {
  content: "\f14c";
}
.fa-share-square:before {
  content: "\f14d";
}
.fa-compass:before {
  content: "\f14e";
}
.fa-toggle-down:before,
.fa-caret-square-o-down:before {
  content: "\f150";
}
.fa-toggle-up:before,
.fa-caret-square-o-up:before {
  content: "\f151";
}
.fa-toggle-right:before,
.fa-caret-square-o-right:before {
  content: "\f152";
}
.fa-euro:before,
.fa-eur:before {
  content: "\f153";
}
.fa-gbp:before {
  content: "\f154";
}
.fa-dollar:before,
.fa-usd:before {
  content: "\f155";
}
.fa-rupee:before,
.fa-inr:before {
  content: "\f156";
}
.fa-cny:before,
.fa-rmb:before,
.fa-yen:before,
.fa-jpy:before {
  content: "\f157";
}
.fa-ruble:before,
.fa-rouble:before,
.fa-rub:before {
  content: "\f158";
}
.fa-won:before,
.fa-krw:before {
  content: "\f159";
}
.fa-bitcoin:before,
.fa-btc:before {
  content: "\f15a";
}
.fa-file:before {
  content: "\f15b";
}
.fa-file-text:before {
  content: "\f15c";
}
.fa-sort-alpha-asc:before {
  content: "\f15d";
}
.fa-sort-alpha-desc:before {
  content: "\f15e";
}
.fa-sort-amount-asc:before {
  content: "\f160";
}
.fa-sort-amount-desc:before {
  content: "\f161";
}
.fa-sort-numeric-asc:before {
  content: "\f162";
}
.fa-sort-numeric-desc:before {
  content: "\f163";
}
.fa-thumbs-up:before {
  content: "\f164";
}
.fa-thumbs-down:before {
  content: "\f165";
}
.fa-youtube-square:before {
  content: "\f166";
}
.fa-youtube:before {
  content: "\f167";
}
.fa-xing:before {
  content: "\f168";
}
.fa-xing-square:before {
  content: "\f169";
}
.fa-youtube-play:before {
  content: "\f16a";
}
.fa-dropbox:before {
  content: "\f16b";
}
.fa-stack-overflow:before {
  content: "\f16c";
}
.fa-instagram:before {
  content: "\f16d";
}
.fa-flickr:before {
  content: "\f16e";
}
.fa-adn:before {
  content: "\f170";
}
.fa-bitbucket:before {
  content: "\f171";
}
.fa-bitbucket-square:before {
  content: "\f172";
}
.fa-tumblr:before {
  content: "\f173";
}
.fa-tumblr-square:before {
  content: "\f174";
}
.fa-long-arrow-down:before {
  content: "\f175";
}
.fa-long-arrow-up:before {
  content: "\f176";
}
.fa-long-arrow-left:before {
  content: "\f177";
}
.fa-long-arrow-right:before {
  content: "\f178";
}
.fa-apple:before {
  content: "\f179";
}
.fa-windows:before {
  content: "\f17a";
}
.fa-android:before {
  content: "\f17b";
}
.fa-linux:before {
  content: "\f17c";
}
.fa-dribbble:before {
  content: "\f17d";
}
.fa-skype:before {
  content: "\f17e";
}
.fa-foursquare:before {
  content: "\f180";
}
.fa-trello:before {
  content: "\f181";
}
.fa-female:before {
  content: "\f182";
}
.fa-male:before {
  content: "\f183";
}
.fa-gittip:before {
  content: "\f184";
}
.fa-sun-o:before {
  content: "\f185";
}
.fa-moon-o:before {
  content: "\f186";
}
.fa-archive:before {
  content: "\f187";
}
.fa-bug:before {
  content: "\f188";
}
.fa-vk:before {
  content: "\f189";
}
.fa-weibo:before {
  content: "\f18a";
}
.fa-renren:before {
  content: "\f18b";
}
.fa-pagelines:before {
  content: "\f18c";
}
.fa-stack-exchange:before {
  content: "\f18d";
}
.fa-arrow-circle-o-right:before {
  content: "\f18e";
}
.fa-arrow-circle-o-left:before {
  content: "\f190";
}
.fa-toggle-left:before,
.fa-caret-square-o-left:before {
  content: "\f191";
}
.fa-dot-circle-o:before {
  content: "\f192";
}
.fa-wheelchair:before {
  content: "\f193";
}
.fa-vimeo-square:before {
  content: "\f194";
}
.fa-turkish-lira:before,
.fa-try:before {
  content: "\f195";
}
.fa-plus-square-o:before {
  content: "\f196";
}
.fa-space-shuttle:before {
  content: "\f197";
}
.fa-slack:before {
  content: "\f198";
}
.fa-envelope-square:before {
  content: "\f199";
}
.fa-wordpress:before {
  content: "\f19a";
}
.fa-openid:before {
  content: "\f19b";
}
.fa-institution:before,
.fa-bank:before,
.fa-university:before {
  content: "\f19c";
}
.fa-mortar-board:before,
.fa-graduation-cap:before {
  content: "\f19d";
}
.fa-yahoo:before {
  content: "\f19e";
}
.fa-google:before {
  content: "\f1a0";
}
.fa-reddit:before {
  content: "\f1a1";
}
.fa-reddit-square:before {
  content: "\f1a2";
}
.fa-stumbleupon-circle:before {
  content: "\f1a3";
}
.fa-stumbleupon:before {
  content: "\f1a4";
}
.fa-delicious:before {
  content: "\f1a5";
}
.fa-digg:before {
  content: "\f1a6";
}
.fa-pied-piper:before {
  content: "\f1a7";
}
.fa-pied-piper-alt:before {
  content: "\f1a8";
}
.fa-drupal:before {
  content: "\f1a9";
}
.fa-joomla:before {
  content: "\f1aa";
}
.fa-language:before {
  content: "\f1ab";
}
.fa-fax:before {
  content: "\f1ac";
}
.fa-building:before {
  content: "\f1ad";
}
.fa-child:before {
  content: "\f1ae";
}
.fa-paw:before {
  content: "\f1b0";
}
.fa-spoon:before {
  content: "\f1b1";
}
.fa-cube:before {
  content: "\f1b2";
}
.fa-cubes:before {
  content: "\f1b3";
}
.fa-behance:before {
  content: "\f1b4";
}
.fa-behance-square:before {
  content: "\f1b5";
}
.fa-steam:before {
  content: "\f1b6";
}
.fa-steam-square:before {
  content: "\f1b7";
}
.fa-recycle:before {
  content: "\f1b8";
}
.fa-automobile:before,
.fa-car:before {
  content: "\f1b9";
}
.fa-cab:before,
.fa-taxi:before {
  content: "\f1ba";
}
.fa-tree:before {
  content: "\f1bb";
}
.fa-spotify:before {
  content: "\f1bc";
}
.fa-deviantart:before {
  content: "\f1bd";
}
.fa-soundcloud:before {
  content: "\f1be";
}
.fa-database:before {
  content: "\f1c0";
}
.fa-file-pdf-o:before {
  content: "\f1c1";
}
.fa-file-word-o:before {
  content: "\f1c2";
}
.fa-file-excel-o:before {
  content: "\f1c3";
}
.fa-file-powerpoint-o:before {
  content: "\f1c4";
}
.fa-file-photo-o:before,
.fa-file-picture-o:before,
.fa-file-image-o:before {
  content: "\f1c5";
}
.fa-file-zip-o:before,
.fa-file-archive-o:before {
  content: "\f1c6";
}
.fa-file-sound-o:before,
.fa-file-audio-o:before {
  content: "\f1c7";
}
.fa-file-movie-o:before,
.fa-file-video-o:before {
  content: "\f1c8";
}
.fa-file-code-o:before {
  content: "\f1c9";
}
.fa-vine:before {
  content: "\f1ca";
}
.fa-codepen:before {
  content: "\f1cb";
}
.fa-jsfiddle:before {
  content: "\f1cc";
}
.fa-life-bouy:before,
.fa-life-buoy:before,
.fa-life-saver:before,
.fa-support:before,
.fa-life-ring:before {
  content: "\f1cd";
}
.fa-circle-o-notch:before {
  content: "\f1ce";
}
.fa-ra:before,
.fa-rebel:before {
  content: "\f1d0";
}
.fa-ge:before,
.fa-empire:before {
  content: "\f1d1";
}
.fa-git-square:before {
  content: "\f1d2";
}
.fa-git:before {
  content: "\f1d3";
}
.fa-hacker-news:before {
  content: "\f1d4";
}
.fa-tencent-weibo:before {
  content: "\f1d5";
}
.fa-qq:before {
  content: "\f1d6";
}
.fa-wechat:before,
.fa-weixin:before {
  content: "\f1d7";
}
.fa-send:before,
.fa-paper-plane:before {
  content: "\f1d8";
}
.fa-send-o:before,
.fa-paper-plane-o:before {
  content: "\f1d9";
}
.fa-history:before {
  content: "\f1da";
}
.fa-circle-thin:before {
  content: "\f1db";
}
.fa-header:before {
  content: "\f1dc";
}
.fa-paragraph:before {
  content: "\f1dd";
}
.fa-sliders:before {
  content: "\f1de";
}
.fa-share-alt:before {
  content: "\f1e0";
}
.fa-share-alt-square:before {
  content: "\f1e1";
}
.fa-bomb:before {
  content: "\f1e2";
}
.fa-soccer-ball-o:before,
.fa-futbol-o:before {
  content: "\f1e3";
}
.fa-tty:before {
  content: "\f1e4";
}
.fa-binoculars:before {
  content: "\f1e5";
}
.fa-plug:before {
  content: "\f1e6";
}
.fa-slideshare:before {
  content: "\f1e7";
}
.fa-twitch:before {
  content: "\f1e8";
}
.fa-yelp:before {
  content: "\f1e9";
}
.fa-newspaper-o:before {
  content: "\f1ea";
}
.fa-wifi:before {
  content: "\f1eb";
}
.fa-calculator:before {
  content: "\f1ec";
}
.fa-paypal:before {
  content: "\f1ed";
}
.fa-google-wallet:before {
  content: "\f1ee";
}
.fa-cc-visa:before {
  content: "\f1f0";
}
.fa-cc-mastercard:before {
  content: "\f1f1";
}
.fa-cc-discover:before {
  content: "\f1f2";
}
.fa-cc-amex:before {
  content: "\f1f3";
}
.fa-cc-paypal:before {
  content: "\f1f4";
}
.fa-cc-stripe:before {
  content: "\f1f5";
}
.fa-bell-slash:before {
  content: "\f1f6";
}
.fa-bell-slash-o:before {
  content: "\f1f7";
}
.fa-trash:before {
  content: "\f1f8";
}
.fa-copyright:before {
  content: "\f1f9";
}
.fa-at:before {
  content: "\f1fa";
}
.fa-eyedropper:before {
  content: "\f1fb";
}
.fa-paint-brush:before {
  content: "\f1fc";
}
.fa-birthday-cake:before {
  content: "\f1fd";
}
.fa-area-chart:before {
  content: "\f1fe";
}
.fa-pie-chart:before {
  content: "\f200";
}
.fa-line-chart:before {
  content: "\f201";
}
.fa-lastfm:before {
  content: "\f202";
}
.fa-lastfm-square:before {
  content: "\f203";
}
.fa-toggle-off:before {
  content: "\f204";
}
.fa-toggle-on:before {
  content: "\f205";
}
.fa-bicycle:before {
  content: "\f206";
}
.fa-bus:before {
  content: "\f207";
}
.fa-ioxhost:before {
  content: "\f208";
}
.fa-angellist:before {
  content: "\f209";
}
.fa-cc:before {
  content: "\f20a";
}
.fa-shekel:before,
.fa-sheqel:before,
.fa-ils:before {
  content: "\f20b";
}
.fa-meanpath:before {
  content: "\f20c";
}
/*!
*
* IPython base
*
*/
.modal.fade .modal-dialog {
  -webkit-transform: translate(0, 0);
  -ms-transform: translate(0, 0);
  -o-transform: translate(0, 0);
  transform: translate(0, 0);
}
code {
  color: #000;
}
pre {
  font-size: inherit;
  line-height: inherit;
}
label {
  font-weight: normal;
}
/* Make the page background atleast 100% the height of the view port */
/* Make the page itself atleast 70% the height of the view port */
.border-box-sizing {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.corner-all {
  border-radius: 2px;
}
.no-padding {
  padding: 0px;
}
/* Flexible box model classes */
/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
/* This file is a compatability layer.  It allows the usage of flexible box 
model layouts accross multiple browsers, including older browsers.  The newest,
universal implementation of the flexible box model is used when available (see
`Modern browsers` comments below).  Browsers that are known to implement this 
new spec completely include:

    Firefox 28.0+
    Chrome 29.0+
    Internet Explorer 11+ 
    Opera 17.0+

Browsers not listed, including Safari, are supported via the styling under the
`Old browsers` comments below.
*/
.hbox {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
.hbox > * {
  /* Old browsers */
  -webkit-box-flex: 0;
  -moz-box-flex: 0;
  box-flex: 0;
  /* Modern browsers */
  flex: none;
}
.vbox {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.vbox > * {
  /* Old browsers */
  -webkit-box-flex: 0;
  -moz-box-flex: 0;
  box-flex: 0;
  /* Modern browsers */
  flex: none;
}
.hbox.reverse,
.vbox.reverse,
.reverse {
  /* Old browsers */
  -webkit-box-direction: reverse;
  -moz-box-direction: reverse;
  box-direction: reverse;
  /* Modern browsers */
  flex-direction: row-reverse;
}
.hbox.box-flex0,
.vbox.box-flex0,
.box-flex0 {
  /* Old browsers */
  -webkit-box-flex: 0;
  -moz-box-flex: 0;
  box-flex: 0;
  /* Modern browsers */
  flex: none;
  width: auto;
}
.hbox.box-flex1,
.vbox.box-flex1,
.box-flex1 {
  /* Old browsers */
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  /* Modern browsers */
  flex: 1;
}
.hbox.box-flex,
.vbox.box-flex,
.box-flex {
  /* Old browsers */
  /* Old browsers */
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  /* Modern browsers */
  flex: 1;
}
.hbox.box-flex2,
.vbox.box-flex2,
.box-flex2 {
  /* Old browsers */
  -webkit-box-flex: 2;
  -moz-box-flex: 2;
  box-flex: 2;
  /* Modern browsers */
  flex: 2;
}
.box-group1 {
  /*  Deprecated */
  -webkit-box-flex-group: 1;
  -moz-box-flex-group: 1;
  box-flex-group: 1;
}
.box-group2 {
  /* Deprecated */
  -webkit-box-flex-group: 2;
  -moz-box-flex-group: 2;
  box-flex-group: 2;
}
.hbox.start,
.vbox.start,
.start {
  /* Old browsers */
  -webkit-box-pack: start;
  -moz-box-pack: start;
  box-pack: start;
  /* Modern browsers */
  justify-content: flex-start;
}
.hbox.end,
.vbox.end,
.end {
  /* Old browsers */
  -webkit-box-pack: end;
  -moz-box-pack: end;
  box-pack: end;
  /* Modern browsers */
  justify-content: flex-end;
}
.hbox.center,
.vbox.center,
.center {
  /* Old browsers */
  -webkit-box-pack: center;
  -moz-box-pack: center;
  box-pack: center;
  /* Modern browsers */
  justify-content: center;
}
.hbox.baseline,
.vbox.baseline,
.baseline {
  /* Old browsers */
  -webkit-box-pack: baseline;
  -moz-box-pack: baseline;
  box-pack: baseline;
  /* Modern browsers */
  justify-content: baseline;
}
.hbox.stretch,
.vbox.stretch,
.stretch {
  /* Old browsers */
  -webkit-box-pack: stretch;
  -moz-box-pack: stretch;
  box-pack: stretch;
  /* Modern browsers */
  justify-content: stretch;
}
.hbox.align-start,
.vbox.align-start,
.align-start {
  /* Old browsers */
  -webkit-box-align: start;
  -moz-box-align: start;
  box-align: start;
  /* Modern browsers */
  align-items: flex-start;
}
.hbox.align-end,
.vbox.align-end,
.align-end {
  /* Old browsers */
  -webkit-box-align: end;
  -moz-box-align: end;
  box-align: end;
  /* Modern browsers */
  align-items: flex-end;
}
.hbox.align-center,
.vbox.align-center,
.align-center {
  /* Old browsers */
  -webkit-box-align: center;
  -moz-box-align: center;
  box-align: center;
  /* Modern browsers */
  align-items: center;
}
.hbox.align-baseline,
.vbox.align-baseline,
.align-baseline {
  /* Old browsers */
  -webkit-box-align: baseline;
  -moz-box-align: baseline;
  box-align: baseline;
  /* Modern browsers */
  align-items: baseline;
}
.hbox.align-stretch,
.vbox.align-stretch,
.align-stretch {
  /* Old browsers */
  -webkit-box-align: stretch;
  -moz-box-align: stretch;
  box-align: stretch;
  /* Modern browsers */
  align-items: stretch;
}
div.error {
  margin: 2em;
  text-align: center;
}
div.error > h1 {
  font-size: 500%;
  line-height: normal;
}
div.error > p {
  font-size: 200%;
  line-height: normal;
}
div.traceback-wrapper {
  text-align: left;
  max-width: 800px;
  margin: auto;
}
/**
 * Primary styles
 *
 * Author: Jupyter Development Team
 */
body {
  background-color: #fff;
  /* This makes sure that the body covers the entire window and needs to
       be in a different element than the display: box in wrapper below */
  position: absolute;
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
  overflow: visible;
}
body > #header {
  /* Initially hidden to prevent FLOUC */
  display: none;
  background-color: #fff;
  /* Display over codemirror */
  position: relative;
  z-index: 100;
}
body > #header #header-container {
  padding-bottom: 5px;
  padding-top: 5px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
body > #header .header-bar {
  width: 100%;
  height: 1px;
  background: #e7e7e7;
  margin-bottom: -1px;
}
@media print {
  body > #header {
    display: none !important;
  }
}
#header-spacer {
  width: 100%;
  visibility: hidden;
}
@media print {
  #header-spacer {
    display: none;
  }
}
#ipython_notebook {
  padding-left: 0px;
  padding-top: 1px;
  padding-bottom: 1px;
}
@media (max-width: 991px) {
  #ipython_notebook {
    margin-left: 10px;
  }
}
[dir="rtl"] #ipython_notebook {
  float: right !important;
}
#noscript {
  width: auto;
  padding-top: 16px;
  padding-bottom: 16px;
  text-align: center;
  font-size: 22px;
  color: red;
  font-weight: bold;
}
#ipython_notebook img {
  height: 28px;
}
#site {
  width: 100%;
  display: none;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  overflow: auto;
}
@media print {
  #site {
    height: auto !important;
  }
}
/* Smaller buttons */
.ui-button .ui-button-text {
  padding: 0.2em 0.8em;
  font-size: 77%;
}
input.ui-button {
  padding: 0.3em 0.9em;
}
span#login_widget {
  float: right;
}
span#login_widget > .button,
#logout {
  color: #333;
  background-color: #fff;
  border-color: #ccc;
}
span#login_widget > .button:focus,
#logout:focus,
span#login_widget > .button.focus,
#logout.focus {
  color: #333;
  background-color: #e6e6e6;
  border-color: #8c8c8c;
}
span#login_widget > .button:hover,
#logout:hover {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
span#login_widget > .button:active,
#logout:active,
span#login_widget > .button.active,
#logout.active,
.open > .dropdown-togglespan#login_widget > .button,
.open > .dropdown-toggle#logout {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
span#login_widget > .button:active:hover,
#logout:active:hover,
span#login_widget > .button.active:hover,
#logout.active:hover,
.open > .dropdown-togglespan#login_widget > .button:hover,
.open > .dropdown-toggle#logout:hover,
span#login_widget > .button:active:focus,
#logout:active:focus,
span#login_widget > .button.active:focus,
#logout.active:focus,
.open > .dropdown-togglespan#login_widget > .button:focus,
.open > .dropdown-toggle#logout:focus,
span#login_widget > .button:active.focus,
#logout:active.focus,
span#login_widget > .button.active.focus,
#logout.active.focus,
.open > .dropdown-togglespan#login_widget > .button.focus,
.open > .dropdown-toggle#logout.focus {
  color: #333;
  background-color: #d4d4d4;
  border-color: #8c8c8c;
}
span#login_widget > .button:active,
#logout:active,
span#login_widget > .button.active,
#logout.active,
.open > .dropdown-togglespan#login_widget > .button,
.open > .dropdown-toggle#logout {
  background-image: none;
}
span#login_widget > .button.disabled:hover,
#logout.disabled:hover,
span#login_widget > .button[disabled]:hover,
#logout[disabled]:hover,
fieldset[disabled] span#login_widget > .button:hover,
fieldset[disabled] #logout:hover,
span#login_widget > .button.disabled:focus,
#logout.disabled:focus,
span#login_widget > .button[disabled]:focus,
#logout[disabled]:focus,
fieldset[disabled] span#login_widget > .button:focus,
fieldset[disabled] #logout:focus,
span#login_widget > .button.disabled.focus,
#logout.disabled.focus,
span#login_widget > .button[disabled].focus,
#logout[disabled].focus,
fieldset[disabled] span#login_widget > .button.focus,
fieldset[disabled] #logout.focus {
  background-color: #fff;
  border-color: #ccc;
}
span#login_widget > .button .badge,
#logout .badge {
  color: #fff;
  background-color: #333;
}
.nav-header {
  text-transform: none;
}
#header > span {
  margin-top: 10px;
}
.modal_stretch .modal-dialog {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 80vh;
}
.modal_stretch .modal-dialog .modal-body {
  max-height: calc(100vh - 200px);
  overflow: auto;
  flex: 1;
}
@media (min-width: 768px) {
  .modal .modal-dialog {
    width: 700px;
  }
}
@media (min-width: 768px) {
  select.form-control {
    margin-left: 12px;
    margin-right: 12px;
  }
}
/*!
*
* IPython auth
*
*/
.center-nav {
  display: inline-block;
  margin-bottom: -4px;
}
/*!
*
* IPython tree view
*
*/
/* We need an invisible input field on top of the sentense*/
/* "Drag file onto the list ..." */
.alternate_upload {
  background-color: none;
  display: inline;
}
.alternate_upload.form {
  padding: 0;
  margin: 0;
}
.alternate_upload input.fileinput {
  text-align: center;
  vertical-align: middle;
  display: inline;
  opacity: 0;
  z-index: 2;
  width: 12ex;
  margin-right: -12ex;
}
.alternate_upload .btn-upload {
  height: 22px;
}
/**
 * Primary styles
 *
 * Author: Jupyter Development Team
 */
[dir="rtl"] #tabs li {
  float: right;
}
ul#tabs {
  margin-bottom: 4px;
}
[dir="rtl"] ul#tabs {
  margin-right: 0px;
}
ul#tabs a {
  padding-top: 6px;
  padding-bottom: 4px;
}
ul.breadcrumb a:focus,
ul.breadcrumb a:hover {
  text-decoration: none;
}
ul.breadcrumb i.icon-home {
  font-size: 16px;
  margin-right: 4px;
}
ul.breadcrumb span {
  color: #5e5e5e;
}
.list_toolbar {
  padding: 4px 0 4px 0;
  vertical-align: middle;
}
.list_toolbar .tree-buttons {
  padding-top: 1px;
}
[dir="rtl"] .list_toolbar .tree-buttons {
  float: left !important;
}
[dir="rtl"] .list_toolbar .pull-right {
  padding-top: 1px;
  float: left !important;
}
[dir="rtl"] .list_toolbar .pull-left {
  float: right !important;
}
.dynamic-buttons {
  padding-top: 3px;
  display: inline-block;
}
.list_toolbar [class*="span"] {
  min-height: 24px;
}
.list_header {
  font-weight: bold;
  background-color: #EEE;
}
.list_placeholder {
  font-weight: bold;
  padding-top: 4px;
  padding-bottom: 4px;
  padding-left: 7px;
  padding-right: 7px;
}
.list_container {
  margin-top: 4px;
  margin-bottom: 20px;
  border: 1px solid #ddd;
  border-radius: 2px;
}
.list_container > div {
  border-bottom: 1px solid #ddd;
}
.list_container > div:hover .list-item {
  background-color: red;
}
.list_container > div:last-child {
  border: none;
}
.list_item:hover .list_item {
  background-color: #ddd;
}
.list_item a {
  text-decoration: none;
}
.list_item:hover {
  background-color: #fafafa;
}
.list_header > div,
.list_item > div {
  padding-top: 4px;
  padding-bottom: 4px;
  padding-left: 7px;
  padding-right: 7px;
  line-height: 22px;
}
.list_header > div input,
.list_item > div input {
  margin-right: 7px;
  margin-left: 14px;
  vertical-align: baseline;
  line-height: 22px;
  position: relative;
  top: -1px;
}
.list_header > div .item_link,
.list_item > div .item_link {
  margin-left: -1px;
  vertical-align: baseline;
  line-height: 22px;
}
.new-file input[type=checkbox] {
  visibility: hidden;
}
.item_name {
  line-height: 22px;
  height: 24px;
}
.item_icon {
  font-size: 14px;
  color: #5e5e5e;
  margin-right: 7px;
  margin-left: 7px;
  line-height: 22px;
  vertical-align: baseline;
}
.item_buttons {
  line-height: 1em;
  margin-left: -5px;
}
.item_buttons .btn,
.item_buttons .btn-group,
.item_buttons .input-group {
  float: left;
}
.item_buttons > .btn,
.item_buttons > .btn-group,
.item_buttons > .input-group {
  margin-left: 5px;
}
.item_buttons .btn {
  min-width: 13ex;
}
.item_buttons .running-indicator {
  padding-top: 4px;
  color: #5cb85c;
}
.item_buttons .kernel-name {
  padding-top: 4px;
  color: #5bc0de;
  margin-right: 7px;
  float: left;
}
.toolbar_info {
  height: 24px;
  line-height: 24px;
}
.list_item input:not([type=checkbox]) {
  padding-top: 3px;
  padding-bottom: 3px;
  height: 22px;
  line-height: 14px;
  margin: 0px;
}
.highlight_text {
  color: blue;
}
#project_name {
  display: inline-block;
  padding-left: 7px;
  margin-left: -2px;
}
#project_name > .breadcrumb {
  padding: 0px;
  margin-bottom: 0px;
  background-color: transparent;
  font-weight: bold;
}
#tree-selector {
  padding-right: 0px;
}
[dir="rtl"] #tree-selector a {
  float: right;
}
#button-select-all {
  min-width: 50px;
}
#select-all {
  margin-left: 7px;
  margin-right: 2px;
}
.menu_icon {
  margin-right: 2px;
}
.tab-content .row {
  margin-left: 0px;
  margin-right: 0px;
}
.folder_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f114";
}
.folder_icon:before.pull-left {
  margin-right: .3em;
}
.folder_icon:before.pull-right {
  margin-left: .3em;
}
.notebook_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f02d";
  position: relative;
  top: -1px;
}
.notebook_icon:before.pull-left {
  margin-right: .3em;
}
.notebook_icon:before.pull-right {
  margin-left: .3em;
}
.running_notebook_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f02d";
  position: relative;
  top: -1px;
  color: #5cb85c;
}
.running_notebook_icon:before.pull-left {
  margin-right: .3em;
}
.running_notebook_icon:before.pull-right {
  margin-left: .3em;
}
.file_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f016";
  position: relative;
  top: -2px;
}
.file_icon:before.pull-left {
  margin-right: .3em;
}
.file_icon:before.pull-right {
  margin-left: .3em;
}
#notebook_toolbar .pull-right {
  padding-top: 0px;
  margin-right: -1px;
}
ul#new-menu {
  left: auto;
  right: 0;
}
[dir="rtl"] #new-menu {
  text-align: right;
}
.kernel-menu-icon {
  padding-right: 12px;
  width: 24px;
  content: "\f096";
}
.kernel-menu-icon:before {
  content: "\f096";
}
.kernel-menu-icon-current:before {
  content: "\f00c";
}
#tab_content {
  padding-top: 20px;
}
#running .panel-group .panel {
  margin-top: 3px;
  margin-bottom: 1em;
}
#running .panel-group .panel .panel-heading {
  background-color: #EEE;
  padding-top: 4px;
  padding-bottom: 4px;
  padding-left: 7px;
  padding-right: 7px;
  line-height: 22px;
}
#running .panel-group .panel .panel-heading a:focus,
#running .panel-group .panel .panel-heading a:hover {
  text-decoration: none;
}
#running .panel-group .panel .panel-body {
  padding: 0px;
}
#running .panel-group .panel .panel-body .list_container {
  margin-top: 0px;
  margin-bottom: 0px;
  border: 0px;
  border-radius: 0px;
}
#running .panel-group .panel .panel-body .list_container .list_item {
  border-bottom: 1px solid #ddd;
}
#running .panel-group .panel .panel-body .list_container .list_item:last-child {
  border-bottom: 0px;
}
[dir="rtl"] #running .col-sm-8 {
  float: right !important;
}
.delete-button {
  display: none;
}
.duplicate-button {
  display: none;
}
.rename-button {
  display: none;
}
.shutdown-button {
  display: none;
}
.dynamic-instructions {
  display: inline-block;
  padding-top: 4px;
}
/*!
*
* IPython text editor webapp
*
*/
.selected-keymap i.fa {
  padding: 0px 5px;
}
.selected-keymap i.fa:before {
  content: "\f00c";
}
#mode-menu {
  overflow: auto;
  max-height: 20em;
}
.edit_app #header {
  -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
.edit_app #menubar .navbar {
  /* Use a negative 1 bottom margin, so the border overlaps the border of the
    header */
  margin-bottom: -1px;
}
.dirty-indicator {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  width: 20px;
}
.dirty-indicator.pull-left {
  margin-right: .3em;
}
.dirty-indicator.pull-right {
  margin-left: .3em;
}
.dirty-indicator-dirty {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  width: 20px;
}
.dirty-indicator-dirty.pull-left {
  margin-right: .3em;
}
.dirty-indicator-dirty.pull-right {
  margin-left: .3em;
}
.dirty-indicator-clean {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  width: 20px;
}
.dirty-indicator-clean.pull-left {
  margin-right: .3em;
}
.dirty-indicator-clean.pull-right {
  margin-left: .3em;
}
.dirty-indicator-clean:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f00c";
}
.dirty-indicator-clean:before.pull-left {
  margin-right: .3em;
}
.dirty-indicator-clean:before.pull-right {
  margin-left: .3em;
}
#filename {
  font-size: 16pt;
  display: table;
  padding: 0px 5px;
}
#current-mode {
  padding-left: 5px;
  padding-right: 5px;
}
#texteditor-backdrop {
  padding-top: 20px;
  padding-bottom: 20px;
}
@media not print {
  #texteditor-backdrop {
    background-color: #EEE;
  }
}
@media print {
  #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
  #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
    background-color: #fff;
  }
}
@media not print {
  #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
  #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
    background-color: #fff;
  }
}
@media not print {
  #texteditor-backdrop #texteditor-container {
    padding: 0px;
    background-color: #fff;
    -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
    box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  }
}
/*!
*
* IPython notebook
*
*/
/* CSS font colors for translated ANSI colors. */
.ansibold {
  font-weight: bold;
}
/* use dark versions for foreground, to improve visibility */
.ansiblack {
  color: black;
}
.ansired {
  color: darkred;
}
.ansigreen {
  color: darkgreen;
}
.ansiyellow {
  color: #c4a000;
}
.ansiblue {
  color: darkblue;
}
.ansipurple {
  color: darkviolet;
}
.ansicyan {
  color: steelblue;
}
.ansigray {
  color: gray;
}
/* and light for background, for the same reason */
.ansibgblack {
  background-color: black;
}
.ansibgred {
  background-color: red;
}
.ansibggreen {
  background-color: green;
}
.ansibgyellow {
  background-color: yellow;
}
.ansibgblue {
  background-color: blue;
}
.ansibgpurple {
  background-color: magenta;
}
.ansibgcyan {
  background-color: cyan;
}
.ansibggray {
  background-color: gray;
}
div.cell {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  border-radius: 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  border-width: 1px;
  border-style: solid;
  border-color: transparent;
  width: 100%;
  padding: 5px;
  /* This acts as a spacer between cells, that is outside the border */
  margin: 0px;
  outline: none;
  border-left-width: 1px;
  padding-left: 5px;
  background: linear-gradient(to right, transparent -40px, transparent 1px, transparent 1px, transparent 100%);
}
div.cell.jupyter-soft-selected {
  border-left-color: #90CAF9;
  border-left-color: #E3F2FD;
  border-left-width: 1px;
  padding-left: 5px;
  border-right-color: #E3F2FD;
  border-right-width: 1px;
  background: #E3F2FD;
}
@media print {
  div.cell.jupyter-soft-selected {
    border-color: transparent;
  }
}
div.cell.selected {
  border-color: #ababab;
  border-left-width: 0px;
  padding-left: 6px;
  background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 5px, transparent 5px, transparent 100%);
}
@media print {
  div.cell.selected {
    border-color: transparent;
  }
}
div.cell.selected.jupyter-soft-selected {
  border-left-width: 0;
  padding-left: 6px;
  background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 7px, #E3F2FD 7px, #E3F2FD 100%);
}
.edit_mode div.cell.selected {
  border-color: #66BB6A;
  border-left-width: 0px;
  padding-left: 6px;
  background: linear-gradient(to right, #66BB6A -40px, #66BB6A 5px, transparent 5px, transparent 100%);
}
@media print {
  .edit_mode div.cell.selected {
    border-color: transparent;
  }
}
.prompt {
  /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
  min-width: 14ex;
  /* This padding is tuned to match the padding on the CodeMirror editor. */
  padding: 0.4em;
  margin: 0px;
  font-family: monospace;
  text-align: right;
  /* This has to match that of the the CodeMirror class line-height below */
  line-height: 1.21429em;
  /* Don't highlight prompt number selection */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  /* Use default cursor */
  cursor: default;
}
@media (max-width: 540px) {
  .prompt {
    text-align: left;
  }
}
div.inner_cell {
  min-width: 0;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /* Old browsers */
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  /* Modern browsers */
  flex: 1;
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_area {
  border: 1px solid #cfcfcf;
  border-radius: 2px;
  background: #f7f7f7;
  line-height: 1.21429em;
}
/* This is needed so that empty prompt areas can collapse to zero height when there
   is no content in the output_subarea and the prompt. The main purpose of this is
   to make sure that empty JavaScript output_subareas have no height. */
div.prompt:empty {
  padding-top: 0;
  padding-bottom: 0;
}
div.unrecognized_cell {
  padding: 5px 5px 5px 0px;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
div.unrecognized_cell .inner_cell {
  border-radius: 2px;
  padding: 5px;
  font-weight: bold;
  color: red;
  border: 1px solid #cfcfcf;
  background: #eaeaea;
}
div.unrecognized_cell .inner_cell a {
  color: inherit;
  text-decoration: none;
}
div.unrecognized_cell .inner_cell a:hover {
  color: inherit;
  text-decoration: none;
}
@media (max-width: 540px) {
  div.unrecognized_cell > div.prompt {
    display: none;
  }
}
div.code_cell {
  /* avoid page breaking on code cells when printing */
}
@media print {
  div.code_cell {
    page-break-inside: avoid;
  }
}
/* any special styling for code cells that are currently running goes here */
div.input {
  page-break-inside: avoid;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
@media (max-width: 540px) {
  div.input {
    /* Old browsers */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-box-align: stretch;
    display: -moz-box;
    -moz-box-orient: vertical;
    -moz-box-align: stretch;
    display: box;
    box-orient: vertical;
    box-align: stretch;
    /* Modern browsers */
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_prompt {
  color: #303F9F;
  border-top: 1px solid transparent;
}
div.input_area > div.highlight {
  margin: 0.4em;
  border: none;
  padding: 0px;
  background-color: transparent;
}
div.input_area > div.highlight > pre {
  margin: 0px;
  border: none;
  padding: 0px;
  background-color: transparent;
}
/* The following gets added to the <head> if it is detected that the user has a
 * monospace font with inconsistent normal/bold/italic height.  See
 * notebookmain.js.  Such fonts will have keywords vertically offset with
 * respect to the rest of the text.  The user should select a better font.
 * See: https://github.com/ipython/ipython/issues/1503
 *
 * .CodeMirror span {
 *      vertical-align: bottom;
 * }
 */
.CodeMirror {
  line-height: 1.21429em;
  /* Changed from 1em to our global default */
  font-size: 14px;
  height: auto;
  /* Changed to auto to autogrow */
  background: none;
  /* Changed from white to allow our bg to show through */
}
.CodeMirror-scroll {
  /*  The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
  /*  We have found that if it is visible, vertical scrollbars appear with font size changes.*/
  overflow-y: hidden;
  overflow-x: auto;
}
.CodeMirror-lines {
  /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
  /* we have set a different line-height and want this to scale with that. */
  padding: 0.4em;
}
.CodeMirror-linenumber {
  padding: 0 8px 0 4px;
}
.CodeMirror-gutters {
  border-bottom-left-radius: 2px;
  border-top-left-radius: 2px;
}
.CodeMirror pre {
  /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
  /* .CodeMirror-lines */
  padding: 0;
  border: 0;
  border-radius: 0;
}
/*

Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
Adapted from GitHub theme

*/
.highlight-base {
  color: #000;
}
.highlight-variable {
  color: #000;
}
.highlight-variable-2 {
  color: #1a1a1a;
}
.highlight-variable-3 {
  color: #333333;
}
.highlight-string {
  color: #BA2121;
}
.highlight-comment {
  color: #408080;
  font-style: italic;
}
.highlight-number {
  color: #080;
}
.highlight-atom {
  color: #88F;
}
.highlight-keyword {
  color: #008000;
  font-weight: bold;
}
.highlight-builtin {
  color: #008000;
}
.highlight-error {
  color: #f00;
}
.highlight-operator {
  color: #AA22FF;
  font-weight: bold;
}
.highlight-meta {
  color: #AA22FF;
}
/* previously not defined, copying from default codemirror */
.highlight-def {
  color: #00f;
}
.highlight-string-2 {
  color: #f50;
}
.highlight-qualifier {
  color: #555;
}
.highlight-bracket {
  color: #997;
}
.highlight-tag {
  color: #170;
}
.highlight-attribute {
  color: #00c;
}
.highlight-header {
  color: blue;
}
.highlight-quote {
  color: #090;
}
.highlight-link {
  color: #00c;
}
/* apply the same style to codemirror */
.cm-s-ipython span.cm-keyword {
  color: #008000;
  font-weight: bold;
}
.cm-s-ipython span.cm-atom {
  color: #88F;
}
.cm-s-ipython span.cm-number {
  color: #080;
}
.cm-s-ipython span.cm-def {
  color: #00f;
}
.cm-s-ipython span.cm-variable {
  color: #000;
}
.cm-s-ipython span.cm-operator {
  color: #AA22FF;
  font-weight: bold;
}
.cm-s-ipython span.cm-variable-2 {
  color: #1a1a1a;
}
.cm-s-ipython span.cm-variable-3 {
  color: #333333;
}
.cm-s-ipython span.cm-comment {
  color: #408080;
  font-style: italic;
}
.cm-s-ipython span.cm-string {
  color: #BA2121;
}
.cm-s-ipython span.cm-string-2 {
  color: #f50;
}
.cm-s-ipython span.cm-meta {
  color: #AA22FF;
}
.cm-s-ipython span.cm-qualifier {
  color: #555;
}
.cm-s-ipython span.cm-builtin {
  color: #008000;
}
.cm-s-ipython span.cm-bracket {
  color: #997;
}
.cm-s-ipython span.cm-tag {
  color: #170;
}
.cm-s-ipython span.cm-attribute {
  color: #00c;
}
.cm-s-ipython span.cm-header {
  color: blue;
}
.cm-s-ipython span.cm-quote {
  color: #090;
}
.cm-s-ipython span.cm-link {
  color: #00c;
}
.cm-s-ipython span.cm-error {
  color: #f00;
}
.cm-s-ipython span.cm-tab {
  background: url();
  background-position: right;
  background-repeat: no-repeat;
}
div.output_wrapper {
  /* this position must be relative to enable descendents to be absolute within it */
  position: relative;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  z-index: 1;
}
/* class for the output area when it should be height-limited */
div.output_scroll {
  /* ideally, this would be max-height, but FF barfs all over that */
  height: 24em;
  /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
  width: 100%;
  overflow: auto;
  border-radius: 2px;
  -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
  display: block;
}
/* output div while it is collapsed */
div.output_collapsed {
  margin: 0px;
  padding: 0px;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
div.out_prompt_overlay {
  height: 100%;
  padding: 0px 0.4em;
  position: absolute;
  border-radius: 2px;
}
div.out_prompt_overlay:hover {
  /* use inner shadow to get border that is computed the same on WebKit/FF */
  -webkit-box-shadow: inset 0 0 1px #000;
  box-shadow: inset 0 0 1px #000;
  background: rgba(240, 240, 240, 0.5);
}
div.output_prompt {
  color: #D84315;
}
/* This class is the outer container of all output sections. */
div.output_area {
  padding: 0px;
  page-break-inside: avoid;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
div.output_area .MathJax_Display {
  text-align: left !important;
}
div.output_area .rendered_html table {
  margin-left: 0;
  margin-right: 0;
}
div.output_area .rendered_html img {
  margin-left: 0;
  margin-right: 0;
}
div.output_area img,
div.output_area svg {
  max-width: 100%;
  height: auto;
}
div.output_area img.unconfined,
div.output_area svg.unconfined {
  max-width: none;
}
/* This is needed to protect the pre formating from global settings such
   as that of bootstrap */
.output {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: vertical;
  -moz-box-align: stretch;
  display: box;
  box-orient: vertical;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
@media (max-width: 540px) {
  div.output_area {
    /* Old browsers */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-box-align: stretch;
    display: -moz-box;
    -moz-box-orient: vertical;
    -moz-box-align: stretch;
    display: box;
    box-orient: vertical;
    box-align: stretch;
    /* Modern browsers */
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
}
div.output_area pre {
  margin: 0;
  padding: 0;
  border: 0;
  vertical-align: baseline;
  color: black;
  background-color: transparent;
  border-radius: 0;
}
/* This class is for the output subarea inside the output_area and after
   the prompt div. */
div.output_subarea {
  overflow-x: auto;
  padding: 0.4em;
  /* Old browsers */
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  /* Modern browsers */
  flex: 1;
  max-width: calc(100% - 14ex);
}
div.output_scroll div.output_subarea {
  overflow-x: visible;
}
/* The rest of the output_* classes are for special styling of the different
   output types */
/* all text output has this class: */
div.output_text {
  text-align: left;
  color: #000;
  /* This has to match that of the the CodeMirror class line-height below */
  line-height: 1.21429em;
}
/* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
div.output_stderr {
  background: #fdd;
  /* very light red background for stderr */
}
div.output_latex {
  text-align: left;
}
/* Empty output_javascript divs should have no height */
div.output_javascript:empty {
  padding: 0;
}
.js-error {
  color: darkred;
}
/* raw_input styles */
div.raw_input_container {
  line-height: 1.21429em;
  padding-top: 5px;
}
pre.raw_input_prompt {
  /* nothing needed here. */
}
input.raw_input {
  font-family: monospace;
  font-size: inherit;
  color: inherit;
  width: auto;
  /* make sure input baseline aligns with prompt */
  vertical-align: baseline;
  /* padding + margin = 0.5em between prompt and cursor */
  padding: 0em 0.25em;
  margin: 0em 0.25em;
}
input.raw_input:focus {
  box-shadow: none;
}
p.p-space {
  margin-bottom: 10px;
}
div.output_unrecognized {
  padding: 5px;
  font-weight: bold;
  color: red;
}
div.output_unrecognized a {
  color: inherit;
  text-decoration: none;
}
div.output_unrecognized a:hover {
  color: inherit;
  text-decoration: none;
}
.rendered_html {
  color: #000;
  /* any extras will just be numbers: */
}
.rendered_html em {
  font-style: italic;
}
.rendered_html strong {
  font-weight: bold;
}
.rendered_html u {
  text-decoration: underline;
}
.rendered_html :link {
  text-decoration: underline;
}
.rendered_html :visited {
  text-decoration: underline;
}
.rendered_html h1 {
  font-size: 185.7%;
  margin: 1.08em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
}
.rendered_html h2 {
  font-size: 157.1%;
  margin: 1.27em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
}
.rendered_html h3 {
  font-size: 128.6%;
  margin: 1.55em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
}
.rendered_html h4 {
  font-size: 100%;
  margin: 2em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
}
.rendered_html h5 {
  font-size: 100%;
  margin: 2em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
  font-style: italic;
}
.rendered_html h6 {
  font-size: 100%;
  margin: 2em 0 0 0;
  font-weight: bold;
  line-height: 1.0;
  font-style: italic;
}
.rendered_html h1:first-child {
  margin-top: 0.538em;
}
.rendered_html h2:first-child {
  margin-top: 0.636em;
}
.rendered_html h3:first-child {
  margin-top: 0.777em;
}
.rendered_html h4:first-child {
  margin-top: 1em;
}
.rendered_html h5:first-child {
  margin-top: 1em;
}
.rendered_html h6:first-child {
  margin-top: 1em;
}
.rendered_html ul {
  list-style: disc;
  margin: 0em 2em;
  padding-left: 0px;
}
.rendered_html ul ul {
  list-style: square;
  margin: 0em 2em;
}
.rendered_html ul ul ul {
  list-style: circle;
  margin: 0em 2em;
}
.rendered_html ol {
  list-style: decimal;
  margin: 0em 2em;
  padding-left: 0px;
}
.rendered_html ol ol {
  list-style: upper-alpha;
  margin: 0em 2em;
}
.rendered_html ol ol ol {
  list-style: lower-alpha;
  margin: 0em 2em;
}
.rendered_html ol ol ol ol {
  list-style: lower-roman;
  margin: 0em 2em;
}
.rendered_html ol ol ol ol ol {
  list-style: decimal;
  margin: 0em 2em;
}
.rendered_html * + ul {
  margin-top: 1em;
}
.rendered_html * + ol {
  margin-top: 1em;
}
.rendered_html hr {
  color: black;
  background-color: black;
}
.rendered_html pre {
  margin: 1em 2em;
}
.rendered_html pre,
.rendered_html code {
  border: 0;
  background-color: #fff;
  color: #000;
  font-size: 100%;
  padding: 0px;
}
.rendered_html blockquote {
  margin: 1em 2em;
}
.rendered_html table {
  margin-left: auto;
  margin-right: auto;
  border: 1px solid black;
  border-collapse: collapse;
}
.rendered_html tr,
.rendered_html th,
.rendered_html td {
  border: 1px solid black;
  border-collapse: collapse;
  margin: 1em 2em;
}
.rendered_html td,
.rendered_html th {
  text-align: left;
  vertical-align: middle;
  padding: 4px;
}
.rendered_html th {
  font-weight: bold;
}
.rendered_html * + table {
  margin-top: 1em;
}
.rendered_html p {
  text-align: left;
}
.rendered_html * + p {
  margin-top: 1em;
}
.rendered_html img {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
.rendered_html * + img {
  margin-top: 1em;
}
.rendered_html img,
.rendered_html svg {
  max-width: 100%;
  height: auto;
}
.rendered_html img.unconfined,
.rendered_html svg.unconfined {
  max-width: none;
}
div.text_cell {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
@media (max-width: 540px) {
  div.text_cell > div.prompt {
    display: none;
  }
}
div.text_cell_render {
  /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
  outline: none;
  resize: none;
  width: inherit;
  border-style: none;
  padding: 0.5em 0.5em 0.5em 0.4em;
  color: #000;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
a.anchor-link:link {
  text-decoration: none;
  padding: 0px 20px;
  visibility: hidden;
}
h1:hover .anchor-link,
h2:hover .anchor-link,
h3:hover .anchor-link,
h4:hover .anchor-link,
h5:hover .anchor-link,
h6:hover .anchor-link {
  visibility: visible;
}
.text_cell.rendered .input_area {
  display: none;
}
.text_cell.rendered .rendered_html {
  overflow-x: auto;
  overflow-y: hidden;
}
.text_cell.unrendered .text_cell_render {
  display: none;
}
.cm-header-1,
.cm-header-2,
.cm-header-3,
.cm-header-4,
.cm-header-5,
.cm-header-6 {
  font-weight: bold;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.cm-header-1 {
  font-size: 185.7%;
}
.cm-header-2 {
  font-size: 157.1%;
}
.cm-header-3 {
  font-size: 128.6%;
}
.cm-header-4 {
  font-size: 110%;
}
.cm-header-5 {
  font-size: 100%;
  font-style: italic;
}
.cm-header-6 {
  font-size: 100%;
  font-style: italic;
}
/*!
*
* IPython notebook webapp
*
*/
@media (max-width: 767px) {
  .notebook_app {
    padding-left: 0px;
    padding-right: 0px;
  }
}
#ipython-main-app {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  height: 100%;
}
div#notebook_panel {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  height: 100%;
}
div#notebook {
  font-size: 14px;
  line-height: 20px;
  overflow-y: hidden;
  overflow-x: auto;
  width: 100%;
  /* This spaces the page away from the edge of the notebook area */
  padding-top: 20px;
  margin: 0px;
  outline: none;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  min-height: 100%;
}
@media not print {
  #notebook-container {
    padding: 15px;
    background-color: #fff;
    min-height: 0;
    -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
    box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  }
}
@media print {
  #notebook-container {
    width: 100%;
  }
}
div.ui-widget-content {
  border: 1px solid #ababab;
  outline: none;
}
pre.dialog {
  background-color: #f7f7f7;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 0.4em;
  padding-left: 2em;
}
p.dialog {
  padding: 0.2em;
}
/* Word-wrap output correctly.  This is the CSS3 spelling, though Firefox seems
   to not honor it correctly.  Webkit browsers (Chrome, rekonq, Safari) do.
 */
pre,
code,
kbd,
samp {
  white-space: pre-wrap;
}
#fonttest {
  font-family: monospace;
}
p {
  margin-bottom: 0;
}
.end_space {
  min-height: 100px;
  transition: height .2s ease;
}
.notebook_app > #header {
  -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
@media not print {
  .notebook_app {
    background-color: #EEE;
  }
}
kbd {
  border-style: solid;
  border-width: 1px;
  box-shadow: none;
  margin: 2px;
  padding-left: 2px;
  padding-right: 2px;
  padding-top: 1px;
  padding-bottom: 1px;
}
/* CSS for the cell toolbar */
.celltoolbar {
  border: thin solid #CFCFCF;
  border-bottom: none;
  background: #EEE;
  border-radius: 2px 2px 0px 0px;
  width: 100%;
  height: 29px;
  padding-right: 4px;
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
  /* Old browsers */
  -webkit-box-pack: end;
  -moz-box-pack: end;
  box-pack: end;
  /* Modern browsers */
  justify-content: flex-end;
  display: -webkit-flex;
}
@media print {
  .celltoolbar {
    display: none;
  }
}
.ctb_hideshow {
  display: none;
  vertical-align: bottom;
}
/* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
   Cell toolbars are only shown when the ctb_global_show class is also set.
*/
.ctb_global_show .ctb_show.ctb_hideshow {
  display: block;
}
.ctb_global_show .ctb_show + .input_area,
.ctb_global_show .ctb_show + div.text_cell_input,
.ctb_global_show .ctb_show ~ div.text_cell_render {
  border-top-right-radius: 0px;
  border-top-left-radius: 0px;
}
.ctb_global_show .ctb_show ~ div.text_cell_render {
  border: 1px solid #cfcfcf;
}
.celltoolbar {
  font-size: 87%;
  padding-top: 3px;
}
.celltoolbar select {
  display: block;
  width: 100%;
  height: 32px;
  padding: 6px 12px;
  font-size: 13px;
  line-height: 1.42857143;
  color: #555555;
  background-color: #fff;
  background-image: none;
  border: 1px solid #ccc;
  border-radius: 2px;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 1px;
  width: inherit;
  font-size: inherit;
  height: 22px;
  padding: 0px;
  display: inline-block;
}
.celltoolbar select:focus {
  border-color: #66afe9;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.celltoolbar select::-moz-placeholder {
  color: #999;
  opacity: 1;
}
.celltoolbar select:-ms-input-placeholder {
  color: #999;
}
.celltoolbar select::-webkit-input-placeholder {
  color: #999;
}
.celltoolbar select::-ms-expand {
  border: 0;
  background-color: transparent;
}
.celltoolbar select[disabled],
.celltoolbar select[readonly],
fieldset[disabled] .celltoolbar select {
  background-color: #eeeeee;
  opacity: 1;
}
.celltoolbar select[disabled],
fieldset[disabled] .celltoolbar select {
  cursor: not-allowed;
}
textarea.celltoolbar select {
  height: auto;
}
select.celltoolbar select {
  height: 30px;
  line-height: 30px;
}
textarea.celltoolbar select,
select[multiple].celltoolbar select {
  height: auto;
}
.celltoolbar label {
  margin-left: 5px;
  margin-right: 5px;
}
.completions {
  position: absolute;
  z-index: 110;
  overflow: hidden;
  border: 1px solid #ababab;
  border-radius: 2px;
  -webkit-box-shadow: 0px 6px 10px -1px #adadad;
  box-shadow: 0px 6px 10px -1px #adadad;
  line-height: 1;
}
.completions select {
  background: white;
  outline: none;
  border: none;
  padding: 0px;
  margin: 0px;
  overflow: auto;
  font-family: monospace;
  font-size: 110%;
  color: #000;
  width: auto;
}
.completions select option.context {
  color: #286090;
}
#kernel_logo_widget {
  float: right !important;
  float: right;
}
#kernel_logo_widget .current_kernel_logo {
  display: none;
  margin-top: -1px;
  margin-bottom: -1px;
  width: 32px;
  height: 32px;
}
#menubar {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  margin-top: 1px;
}
#menubar .navbar {
  border-top: 1px;
  border-radius: 0px 0px 2px 2px;
  margin-bottom: 0px;
}
#menubar .navbar-toggle {
  float: left;
  padding-top: 7px;
  padding-bottom: 7px;
  border: none;
}
#menubar .navbar-collapse {
  clear: left;
}
.nav-wrapper {
  border-bottom: 1px solid #e7e7e7;
}
i.menu-icon {
  padding-top: 4px;
}
ul#help_menu li a {
  overflow: hidden;
  padding-right: 2.2em;
}
ul#help_menu li a i {
  margin-right: -1.2em;
}
.dropdown-submenu {
  position: relative;
}
.dropdown-submenu > .dropdown-menu {
  top: 0;
  left: 100%;
  margin-top: -6px;
  margin-left: -1px;
}
.dropdown-submenu:hover > .dropdown-menu {
  display: block;
}
.dropdown-submenu > a:after {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: block;
  content: "\f0da";
  float: right;
  color: #333333;
  margin-top: 2px;
  margin-right: -10px;
}
.dropdown-submenu > a:after.pull-left {
  margin-right: .3em;
}
.dropdown-submenu > a:after.pull-right {
  margin-left: .3em;
}
.dropdown-submenu:hover > a:after {
  color: #262626;
}
.dropdown-submenu.pull-left {
  float: none;
}
.dropdown-submenu.pull-left > .dropdown-menu {
  left: -100%;
  margin-left: 10px;
}
#notification_area {
  float: right !important;
  float: right;
  z-index: 10;
}
.indicator_area {
  float: right !important;
  float: right;
  color: #777;
  margin-left: 5px;
  margin-right: 5px;
  width: 11px;
  z-index: 10;
  text-align: center;
  width: auto;
}
#kernel_indicator {
  float: right !important;
  float: right;
  color: #777;
  margin-left: 5px;
  margin-right: 5px;
  width: 11px;
  z-index: 10;
  text-align: center;
  width: auto;
  border-left: 1px solid;
}
#kernel_indicator .kernel_indicator_name {
  padding-left: 5px;
  padding-right: 5px;
}
#modal_indicator {
  float: right !important;
  float: right;
  color: #777;
  margin-left: 5px;
  margin-right: 5px;
  width: 11px;
  z-index: 10;
  text-align: center;
  width: auto;
}
#readonly-indicator {
  float: right !important;
  float: right;
  color: #777;
  margin-left: 5px;
  margin-right: 5px;
  width: 11px;
  z-index: 10;
  text-align: center;
  width: auto;
  margin-top: 2px;
  margin-bottom: 0px;
  margin-left: 0px;
  margin-right: 0px;
  display: none;
}
.modal_indicator:before {
  width: 1.28571429em;
  text-align: center;
}
.edit_mode .modal_indicator:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f040";
}
.edit_mode .modal_indicator:before.pull-left {
  margin-right: .3em;
}
.edit_mode .modal_indicator:before.pull-right {
  margin-left: .3em;
}
.command_mode .modal_indicator:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: ' ';
}
.command_mode .modal_indicator:before.pull-left {
  margin-right: .3em;
}
.command_mode .modal_indicator:before.pull-right {
  margin-left: .3em;
}
.kernel_idle_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f10c";
}
.kernel_idle_icon:before.pull-left {
  margin-right: .3em;
}
.kernel_idle_icon:before.pull-right {
  margin-left: .3em;
}
.kernel_busy_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f111";
}
.kernel_busy_icon:before.pull-left {
  margin-right: .3em;
}
.kernel_busy_icon:before.pull-right {
  margin-left: .3em;
}
.kernel_dead_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f1e2";
}
.kernel_dead_icon:before.pull-left {
  margin-right: .3em;
}
.kernel_dead_icon:before.pull-right {
  margin-left: .3em;
}
.kernel_disconnected_icon:before {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  content: "\f127";
}
.kernel_disconnected_icon:before.pull-left {
  margin-right: .3em;
}
.kernel_disconnected_icon:before.pull-right {
  margin-left: .3em;
}
.notification_widget {
  color: #777;
  z-index: 10;
  background: rgba(240, 240, 240, 0.5);
  margin-right: 4px;
  color: #333;
  background-color: #fff;
  border-color: #ccc;
}
.notification_widget:focus,
.notification_widget.focus {
  color: #333;
  background-color: #e6e6e6;
  border-color: #8c8c8c;
}
.notification_widget:hover {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.notification_widget:active,
.notification_widget.active,
.open > .dropdown-toggle.notification_widget {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.notification_widget:active:hover,
.notification_widget.active:hover,
.open > .dropdown-toggle.notification_widget:hover,
.notification_widget:active:focus,
.notification_widget.active:focus,
.open > .dropdown-toggle.notification_widget:focus,
.notification_widget:active.focus,
.notification_widget.active.focus,
.open > .dropdown-toggle.notification_widget.focus {
  color: #333;
  background-color: #d4d4d4;
  border-color: #8c8c8c;
}
.notification_widget:active,
.notification_widget.active,
.open > .dropdown-toggle.notification_widget {
  background-image: none;
}
.notification_widget.disabled:hover,
.notification_widget[disabled]:hover,
fieldset[disabled] .notification_widget:hover,
.notification_widget.disabled:focus,
.notification_widget[disabled]:focus,
fieldset[disabled] .notification_widget:focus,
.notification_widget.disabled.focus,
.notification_widget[disabled].focus,
fieldset[disabled] .notification_widget.focus {
  background-color: #fff;
  border-color: #ccc;
}
.notification_widget .badge {
  color: #fff;
  background-color: #333;
}
.notification_widget.warning {
  color: #fff;
  background-color: #f0ad4e;
  border-color: #eea236;
}
.notification_widget.warning:focus,
.notification_widget.warning.focus {
  color: #fff;
  background-color: #ec971f;
  border-color: #985f0d;
}
.notification_widget.warning:hover {
  color: #fff;
  background-color: #ec971f;
  border-color: #d58512;
}
.notification_widget.warning:active,
.notification_widget.warning.active,
.open > .dropdown-toggle.notification_widget.warning {
  color: #fff;
  background-color: #ec971f;
  border-color: #d58512;
}
.notification_widget.warning:active:hover,
.notification_widget.warning.active:hover,
.open > .dropdown-toggle.notification_widget.warning:hover,
.notification_widget.warning:active:focus,
.notification_widget.warning.active:focus,
.open > .dropdown-toggle.notification_widget.warning:focus,
.notification_widget.warning:active.focus,
.notification_widget.warning.active.focus,
.open > .dropdown-toggle.notification_widget.warning.focus {
  color: #fff;
  background-color: #d58512;
  border-color: #985f0d;
}
.notification_widget.warning:active,
.notification_widget.warning.active,
.open > .dropdown-toggle.notification_widget.warning {
  background-image: none;
}
.notification_widget.warning.disabled:hover,
.notification_widget.warning[disabled]:hover,
fieldset[disabled] .notification_widget.warning:hover,
.notification_widget.warning.disabled:focus,
.notification_widget.warning[disabled]:focus,
fieldset[disabled] .notification_widget.warning:focus,
.notification_widget.warning.disabled.focus,
.notification_widget.warning[disabled].focus,
fieldset[disabled] .notification_widget.warning.focus {
  background-color: #f0ad4e;
  border-color: #eea236;
}
.notification_widget.warning .badge {
  color: #f0ad4e;
  background-color: #fff;
}
.notification_widget.success {
  color: #fff;
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.notification_widget.success:focus,
.notification_widget.success.focus {
  color: #fff;
  background-color: #449d44;
  border-color: #255625;
}
.notification_widget.success:hover {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}
.notification_widget.success:active,
.notification_widget.success.active,
.open > .dropdown-toggle.notification_widget.success {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}
.notification_widget.success:active:hover,
.notification_widget.success.active:hover,
.open > .dropdown-toggle.notification_widget.success:hover,
.notification_widget.success:active:focus,
.notification_widget.success.active:focus,
.open > .dropdown-toggle.notification_widget.success:focus,
.notification_widget.success:active.focus,
.notification_widget.success.active.focus,
.open > .dropdown-toggle.notification_widget.success.focus {
  color: #fff;
  background-color: #398439;
  border-color: #255625;
}
.notification_widget.success:active,
.notification_widget.success.active,
.open > .dropdown-toggle.notification_widget.success {
  background-image: none;
}
.notification_widget.success.disabled:hover,
.notification_widget.success[disabled]:hover,
fieldset[disabled] .notification_widget.success:hover,
.notification_widget.success.disabled:focus,
.notification_widget.success[disabled]:focus,
fieldset[disabled] .notification_widget.success:focus,
.notification_widget.success.disabled.focus,
.notification_widget.success[disabled].focus,
fieldset[disabled] .notification_widget.success.focus {
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.notification_widget.success .badge {
  color: #5cb85c;
  background-color: #fff;
}
.notification_widget.info {
  color: #fff;
  background-color: #5bc0de;
  border-color: #46b8da;
}
.notification_widget.info:focus,
.notification_widget.info.focus {
  color: #fff;
  background-color: #31b0d5;
  border-color: #1b6d85;
}
.notification_widget.info:hover {
  color: #fff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.notification_widget.info:active,
.notification_widget.info.active,
.open > .dropdown-toggle.notification_widget.info {
  color: #fff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.notification_widget.info:active:hover,
.notification_widget.info.active:hover,
.open > .dropdown-toggle.notification_widget.info:hover,
.notification_widget.info:active:focus,
.notification_widget.info.active:focus,
.open > .dropdown-toggle.notification_widget.info:focus,
.notification_widget.info:active.focus,
.notification_widget.info.active.focus,
.open > .dropdown-toggle.notification_widget.info.focus {
  color: #fff;
  background-color: #269abc;
  border-color: #1b6d85;
}
.notification_widget.info:active,
.notification_widget.info.active,
.open > .dropdown-toggle.notification_widget.info {
  background-image: none;
}
.notification_widget.info.disabled:hover,
.notification_widget.info[disabled]:hover,
fieldset[disabled] .notification_widget.info:hover,
.notification_widget.info.disabled:focus,
.notification_widget.info[disabled]:focus,
fieldset[disabled] .notification_widget.info:focus,
.notification_widget.info.disabled.focus,
.notification_widget.info[disabled].focus,
fieldset[disabled] .notification_widget.info.focus {
  background-color: #5bc0de;
  border-color: #46b8da;
}
.notification_widget.info .badge {
  color: #5bc0de;
  background-color: #fff;
}
.notification_widget.danger {
  color: #fff;
  background-color: #d9534f;
  border-color: #d43f3a;
}
.notification_widget.danger:focus,
.notification_widget.danger.focus {
  color: #fff;
  background-color: #c9302c;
  border-color: #761c19;
}
.notification_widget.danger:hover {
  color: #fff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.notification_widget.danger:active,
.notification_widget.danger.active,
.open > .dropdown-toggle.notification_widget.danger {
  color: #fff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.notification_widget.danger:active:hover,
.notification_widget.danger.active:hover,
.open > .dropdown-toggle.notification_widget.danger:hover,
.notification_widget.danger:active:focus,
.notification_widget.danger.active:focus,
.open > .dropdown-toggle.notification_widget.danger:focus,
.notification_widget.danger:active.focus,
.notification_widget.danger.active.focus,
.open > .dropdown-toggle.notification_widget.danger.focus {
  color: #fff;
  background-color: #ac2925;
  border-color: #761c19;
}
.notification_widget.danger:active,
.notification_widget.danger.active,
.open > .dropdown-toggle.notification_widget.danger {
  background-image: none;
}
.notification_widget.danger.disabled:hover,
.notification_widget.danger[disabled]:hover,
fieldset[disabled] .notification_widget.danger:hover,
.notification_widget.danger.disabled:focus,
.notification_widget.danger[disabled]:focus,
fieldset[disabled] .notification_widget.danger:focus,
.notification_widget.danger.disabled.focus,
.notification_widget.danger[disabled].focus,
fieldset[disabled] .notification_widget.danger.focus {
  background-color: #d9534f;
  border-color: #d43f3a;
}
.notification_widget.danger .badge {
  color: #d9534f;
  background-color: #fff;
}
div#pager {
  background-color: #fff;
  font-size: 14px;
  line-height: 20px;
  overflow: hidden;
  display: none;
  position: fixed;
  bottom: 0px;
  width: 100%;
  max-height: 50%;
  padding-top: 8px;
  -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  /* Display over codemirror */
  z-index: 100;
  /* Hack which prevents jquery ui resizable from changing top. */
  top: auto !important;
}
div#pager pre {
  line-height: 1.21429em;
  color: #000;
  background-color: #f7f7f7;
  padding: 0.4em;
}
div#pager #pager-button-area {
  position: absolute;
  top: 8px;
  right: 20px;
}
div#pager #pager-contents {
  position: relative;
  overflow: auto;
  width: 100%;
  height: 100%;
}
div#pager #pager-contents #pager-container {
  position: relative;
  padding: 15px 0px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
div#pager .ui-resizable-handle {
  top: 0px;
  height: 8px;
  background: #f7f7f7;
  border-top: 1px solid #cfcfcf;
  border-bottom: 1px solid #cfcfcf;
  /* This injects handle bars (a short, wide = symbol) for 
        the resize handle. */
}
div#pager .ui-resizable-handle::after {
  content: '';
  top: 2px;
  left: 50%;
  height: 3px;
  width: 30px;
  margin-left: -15px;
  position: absolute;
  border-top: 1px solid #cfcfcf;
}
.quickhelp {
  /* Old browsers */
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: stretch;
  display: -moz-box;
  -moz-box-orient: horizontal;
  -moz-box-align: stretch;
  display: box;
  box-orient: horizontal;
  box-align: stretch;
  /* Modern browsers */
  display: flex;
  flex-direction: row;
  align-items: stretch;
  line-height: 1.8em;
}
.shortcut_key {
  display: inline-block;
  width: 21ex;
  text-align: right;
  font-family: monospace;
}
.shortcut_descr {
  display: inline-block;
  /* Old browsers */
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  /* Modern browsers */
  flex: 1;
}
span.save_widget {
  margin-top: 6px;
}
span.save_widget span.filename {
  height: 1em;
  line-height: 1em;
  padding: 3px;
  margin-left: 16px;
  border: none;
  font-size: 146.5%;
  border-radius: 2px;
}
span.save_widget span.filename:hover {
  background-color: #e6e6e6;
}
span.checkpoint_status,
span.autosave_status {
  font-size: small;
}
@media (max-width: 767px) {
  span.save_widget {
    font-size: small;
  }
  span.checkpoint_status,
  span.autosave_status {
    display: none;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  span.checkpoint_status {
    display: none;
  }
  span.autosave_status {
    font-size: x-small;
  }
}
.toolbar {
  padding: 0px;
  margin-left: -5px;
  margin-top: 2px;
  margin-bottom: 5px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.toolbar select,
.toolbar label {
  width: auto;
  vertical-align: middle;
  margin-right: 2px;
  margin-bottom: 0px;
  display: inline;
  font-size: 92%;
  margin-left: 0.3em;
  margin-right: 0.3em;
  padding: 0px;
  padding-top: 3px;
}
.toolbar .btn {
  padding: 2px 8px;
}
.toolbar .btn-group {
  margin-top: 0px;
  margin-left: 5px;
}
#maintoolbar {
  margin-bottom: -3px;
  margin-top: -8px;
  border: 0px;
  min-height: 27px;
  margin-left: 0px;
  padding-top: 11px;
  padding-bottom: 3px;
}
#maintoolbar .navbar-text {
  float: none;
  vertical-align: middle;
  text-align: right;
  margin-left: 5px;
  margin-right: 0px;
  margin-top: 0px;
}
.select-xs {
  height: 24px;
}
.pulse,
.dropdown-menu > li > a.pulse,
li.pulse > a.dropdown-toggle,
li.pulse.open > a.dropdown-toggle {
  background-color: #F37626;
  color: white;
}
/**
 * Primary styles
 *
 * Author: Jupyter Development Team
 */
/** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
 * of chance of beeing generated from the ../less/[samename].less file, you can
 * try to get back the less file by reverting somme commit in history
 **/
/*
 * We'll try to get something pretty, so we
 * have some strange css to have the scroll bar on
 * the left with fix button on the top right of the tooltip
 */
@-moz-keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@-webkit-keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@-moz-keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@-webkit-keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
/*properties of tooltip after "expand"*/
.bigtooltip {
  overflow: auto;
  height: 200px;
  -webkit-transition-property: height;
  -webkit-transition-duration: 500ms;
  -moz-transition-property: height;
  -moz-transition-duration: 500ms;
  transition-property: height;
  transition-duration: 500ms;
}
/*properties of tooltip before "expand"*/
.smalltooltip {
  -webkit-transition-property: height;
  -webkit-transition-duration: 500ms;
  -moz-transition-property: height;
  -moz-transition-duration: 500ms;
  transition-property: height;
  transition-duration: 500ms;
  text-overflow: ellipsis;
  overflow: hidden;
  height: 80px;
}
.tooltipbuttons {
  position: absolute;
  padding-right: 15px;
  top: 0px;
  right: 0px;
}
.tooltiptext {
  /*avoid the button to overlap on some docstring*/
  padding-right: 30px;
}
.ipython_tooltip {
  max-width: 700px;
  /*fade-in animation when inserted*/
  -webkit-animation: fadeOut 400ms;
  -moz-animation: fadeOut 400ms;
  animation: fadeOut 400ms;
  -webkit-animation: fadeIn 400ms;
  -moz-animation: fadeIn 400ms;
  animation: fadeIn 400ms;
  vertical-align: middle;
  background-color: #f7f7f7;
  overflow: visible;
  border: #ababab 1px solid;
  outline: none;
  padding: 3px;
  margin: 0px;
  padding-left: 7px;
  font-family: monospace;
  min-height: 50px;
  -moz-box-shadow: 0px 6px 10px -1px #adadad;
  -webkit-box-shadow: 0px 6px 10px -1px #adadad;
  box-shadow: 0px 6px 10px -1px #adadad;
  border-radius: 2px;
  position: absolute;
  z-index: 1000;
}
.ipython_tooltip a {
  float: right;
}
.ipython_tooltip .tooltiptext pre {
  border: 0;
  border-radius: 0;
  font-size: 100%;
  background-color: #f7f7f7;
}
.pretooltiparrow {
  left: 0px;
  margin: 0px;
  top: -16px;
  width: 40px;
  height: 16px;
  overflow: hidden;
  position: absolute;
}
.pretooltiparrow:before {
  background-color: #f7f7f7;
  border: 1px #ababab solid;
  z-index: 11;
  content: "";
  position: absolute;
  left: 15px;
  top: 10px;
  width: 25px;
  height: 25px;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
}
ul.typeahead-list i {
  margin-left: -10px;
  width: 18px;
}
ul.typeahead-list {
  max-height: 80vh;
  overflow: auto;
}
ul.typeahead-list > li > a {
  /** Firefox bug **/
  /* see https://github.com/jupyter/notebook/issues/559 */
  white-space: normal;
}
.cmd-palette .modal-body {
  padding: 7px;
}
.cmd-palette form {
  background: white;
}
.cmd-palette input {
  outline: none;
}
.no-shortcut {
  display: none;
}
.command-shortcut:before {
  content: "(command)";
  padding-right: 3px;
  color: #777777;
}
.edit-shortcut:before {
  content: "(edit)";
  padding-right: 3px;
  color: #777777;
}
#find-and-replace #replace-preview .match,
#find-and-replace #replace-preview .insert {
  background-color: #BBDEFB;
  border-color: #90CAF9;
  border-style: solid;
  border-width: 1px;
  border-radius: 0px;
}
#find-and-replace #replace-preview .replace .match {
  background-color: #FFCDD2;
  border-color: #EF9A9A;
  border-radius: 0px;
}
#find-and-replace #replace-preview .replace .insert {
  background-color: #C8E6C9;
  border-color: #A5D6A7;
  border-radius: 0px;
}
#find-and-replace #replace-preview {
  max-height: 60vh;
  overflow: auto;
}
#find-and-replace #replace-preview pre {
  padding: 5px 10px;
}
.terminal-app {
  background: #EEE;
}
.terminal-app #header {
  background: #fff;
  -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
  box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
}
.terminal-app .terminal {
  width: 100%;
  float: left;
  font-family: monospace;
  color: white;
  background: black;
  padding: 0.4em;
  border-radius: 2px;
  -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
  box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
}
.terminal-app .terminal,
.terminal-app .terminal dummy-screen {
  line-height: 1em;
  font-size: 14px;
}
.terminal-app .terminal .xterm-rows {
  padding: 10px;
}
.terminal-app .terminal-cursor {
  color: black;
  background: white;
}
.terminal-app #terminado-container {
  margin-top: 20px;
}
/*# sourceMappingURL=style.min.css.map */
    </style>
<style type="text/css">
    .highlight .hll { background-color: #ffffcc }
.highlight  { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
    </style>
<style type="text/css">
    
/* Temporary definitions which will become obsolete with Notebook release 5.0 */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }

.ansi-bold { font-weight: bold; }

    </style>


<style type="text/css">
/* Overrides of notebook CSS for static HTML export */
body {
  overflow: visible;
  padding: 8px;
}

div#notebook {
  overflow: visible;
  border-top: none;
}

@media print {
  div.cell {
    display: block;
    page-break-inside: avoid;
  } 
  div.output_wrapper { 
    display: block;
    page-break-inside: avoid; 
  }
  div.output { 
    display: block;
    page-break-inside: avoid; 
  }
}
</style>

<!-- Custom stylesheet, it must be in the same directory as the html file -->
<link rel="stylesheet" href="custom.css">

<!-- Loading mathjax macro -->
<!-- Load mathjax -->
    <script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
    <!-- MathJax configuration -->
    <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ['$','$'], ["\\(","\\)"] ],
            displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
            processEscapes: true,
            processEnvironments: true
        },
        // Center justify equations in code and markdown cells. Elsewhere
        // we use CSS to left justify single line equations in code cells.
        displayAlign: 'center',
        "HTML-CSS": {
            styles: {'.MathJax_Display': {"margin": 0}},
            linebreaks: { automatic: true }
        }
    });
    </script>
    <!-- End of mathjax configuration --></head>
<body>
  <div tabindex="-1" id="notebook" class="border-box-sizing">
    <div class="container" id="notebook-container">

<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><h1 align='center' style="margin-bottom: 0px"> An end to end implementation of a Machine Learning pipeline </h1></p>
<h4 align='center' style="margin-top: 0px"> SPANDAN MADAN</h4>
<h4 align='center' style="margin-top: 0px"> Visual Computing Group, Harvard University</h4>
<h4 align='center' style="margin-top: 0px"> Computer Science and Artificial Intelligence Laboratory, MIT</h4>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 align='center' style="margin-top: 0px"><a href='https://github.com/Spandan-Madan/DeepLearningProject'>Link to Github Repo</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-1.-Introduction">Section 1. Introduction<a class="anchor-link" href="#Section-1.-Introduction">&#182;</a></h1><h3 id="Background">Background<a class="anchor-link" href="#Background">&#182;</a></h3><p>In the fall of 2016, I was a Teaching Fellow (Harvard's version of TA) for the graduate class on "Advanced Topics in Data Science (CS209/109)" at Harvard University. I was in-charge of designing the class project given to the students, and this tutorial has been built on top of the project I designed for the class.</p>
<h3 id="Why-write-yet-another-Tutorial-on-Machine-Learning-and-Deep-Learning?">Why write yet another Tutorial on Machine Learning and Deep Learning?<a class="anchor-link" href="#Why-write-yet-another-Tutorial-on-Machine-Learning-and-Deep-Learning?">&#182;</a></h3><p>As a researcher on Computer Vision, I come across new blogs and tutorials on ML (Machine Learning) every day. However, most of them are just focussing on introducing the syntax and the terminology relavant to the field. For example - a 15 minute tutorial on Tensorflow using MNIST dataset, or a 10 minute intro to Deep Learning in Keras on Imagenet.</p>
<p>While people are able to copy paste and run the code in these tutorials and feel that working in ML is really not that hard, it doesn't help them at all in using ML for their own purposes. For example, they never introduce you to how you can run the same algorithm on your own dataset. Or, how do you get the dataset if you want to solve a problem. Or, which algorithms do you use - Conventional ML, or Deep Learning? How do you evaluate your models performance? How do you write your own model, as opposed to choosing a ready made architecture? All these form fundamental steps in any Machine Learning pipeline, and it is these steps that take most of our time as ML practitioners.</p>
<p>This tutorial breaks down the whole pipeline, and leads the reader through it step by step in an hope to empower you to actually use ML, and not just feel that it was not too hard. Needless to say, this will take much longer than 15-30 minutes. I believe a weekend would be a good enough estimate.</p>
<h3 id="About-the-Author">About the Author<a class="anchor-link" href="#About-the-Author">&#182;</a></h3><p>I am <a href="http://spandanmadan.com/">Spandan Madan</a>, a graduate student at Harvard University working on Computer Vision. My research work is supervised collaboratively by Professor Hanspeter Pfister at Harvard, and Professor Aude Oliva at MIT. My current research focusses on using Computer Vision and Natural Language Techniques in tandem to build systems capable of reasoning using text and visual elements simultaneusly.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-2.-Project-Outline-:-Multi-Modal-Genre-Classification-for-Movies">Section 2. Project Outline : Multi-Modal Genre Classification for Movies<a class="anchor-link" href="#Section-2.-Project-Outline-:-Multi-Modal-Genre-Classification-for-Movies">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Wow,-that-title-sounds-like-a-handful,-right?-Let's-break-it-down-step-by-step.">Wow, that title sounds like a handful, right? Let's break it down step by step.<a class="anchor-link" href="#Wow,-that-title-sounds-like-a-handful,-right?-Let's-break-it-down-step-by-step.">&#182;</a></h2><h3 id="Q.1.-what-do-we-mean-by-Classification?">Q.1. what do we mean by Classification?<a class="anchor-link" href="#Q.1.-what-do-we-mean-by-Classification?">&#182;</a></h3><p>In machine learning, the task of classification means to use the available data to learn a <i>function</i> which can assign a category to a data point. For example, assign a genre to a movie, like "Romantic Comedy", "Action", "Thriller". Another example could be automatically assigning a category to news articles, like "Sports" and "Politics".</p>
<h3 id="More-Formally">More Formally<a class="anchor-link" href="#More-Formally">&#182;</a></h3><h4 id="Given:">Given:<a class="anchor-link" href="#Given:">&#182;</a></h4><ul>
<li>A data point $x_i$ </li>
<li>A set of categories $y_1,y_2...y_n$ that $x_i$ can belong to. <br></li>
</ul>
<h4 id="Task-:">Task :<a class="anchor-link" href="#Task-:">&#182;</a></h4><p>Predict the correct category $y_k$ for a new data point $x_k$ not present in the given dataset.</p>
<h4 id="Problem-:">Problem :<a class="anchor-link" href="#Problem-:">&#182;</a></h4><p>We don't know how the $x$ and $y$ are related mathematically.</p>
<h4 id="Assumption-:">Assumption :<a class="anchor-link" href="#Assumption-:">&#182;</a></h4><p>We assume there exists a function $f$ relating $x$ and $y$ i.e. $f(x_i)=y_i$</p>
<h4 id="Approach-:">Approach :<a class="anchor-link" href="#Approach-:">&#182;</a></h4><p>Since $f$ is not known, we learn a function $g$, which approximates $f$.</p>
<h4 id="Important-consideration-:">Important consideration :<a class="anchor-link" href="#Important-consideration-:">&#182;</a></h4><ul>
<li><p>If $f(x_i)=g(x_i)=y_i$ for all $x_i$, then the two functions $f$ and $g$ are exactly equal. Needless to say, this won't realistically ever happen, and we'll only be able to approximate the true function $f$ using $g$. This means, sometimes the prediction $g(x_i)$ will not be correct. And essentially, our whole goal is to find a $g$ which makes a really low number of such errors. That's basically all that we're trying to do.</p>
</li>
<li><p>For the sake of completeness, I should mention that this is a specific kind of learning problem which we call "Supervised Learning". Also, the idea that $g$ approximates $f$ well for data not present in our dataset is called "Generalization". It is absolutely paramount that our model generalizes, or else all our claims will only be true about data we already have and our predictions will not be correct.</p>
</li>
<li><p>We will look into generalization a little bit more a little ahead in the tutorial.</p>
</li>
<li><p>Finally, There are several other kinds, but supervised learning is the most popular and well studied kind.</p>
</li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Q.2.-What's-Multi-Modal-Classification-then?">Q.2. What's Multi-Modal Classification then?<a class="anchor-link" href="#Q.2.-What's-Multi-Modal-Classification-then?">&#182;</a></h3><p>In the machine learning community, the term Multi-Modal is used to refer to multiple <i>kinds</i> of data. For example, consider a YouTube video. It can be thought to contain 3 different modalities -</p>
<ul>
<li>The video frames (visual modality)</li>
<li>The audio clip of what's being spoken (audio modality)</li>
<li>Some videos also come with the transcription of the words spoken in the form of subtitles (textual modality)</li>
</ul>
<p>Consider, that I'm interested in classifying a song on YouTube as pop or rock. You can use any of the above 3 modalities to predict the genre - The video, the song itself, or the lyrics. But, needless to say, you can predict it much better if you could use all three simultaneously. This is what we mean by multi-modal classification.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="For-this-project,-we-will-be-using-visual-and-textual-data-to-classify-movie-genres.">For this project, we will be using visual and textual data to classify movie genres.<a class="anchor-link" href="#For-this-project,-we-will-be-using-visual-and-textual-data-to-classify-movie-genres.">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Project-Outline">Project Outline<a class="anchor-link" href="#Project-Outline">&#182;</a></h1><ul>
<li><strong>Scraping a dataset</strong> : The first step is to build a rich data set. We will collect textual and visual data for each movie.</li>
<li><strong>Data pre-processing</strong></li>
<li><strong>Non-deep Machine Learning models&lt;/b&gt; : Probabilistic and Max-Margin Classifiers.</strong></li>
<li><strong>Intuitive theory behind Deep Learning</strong></li>
<li><strong>Deep Models for Visual Data</strong></li>
<li><strong>Deep Models for Text</strong></li>
<li><strong>Potential Extensions</strong></li>
<li><strong>Food for Thought</strong></li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-3.-Building-your-very-own-DataSet.">Section 3. Building your very own DataSet.<a class="anchor-link" href="#Section-3.-Building-your-very-own-DataSet.">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For any machine learning algorithm to work, it is imperative that we collect data which is "representative". Now, let's take a moment to discuss what the word representative mean.</p>
<h3 id="What-data-is-good-data?-OR-What-do-you-mean-by-data-being-&quot;representative&quot;?">What data is good data? OR What do you mean by data being "representative"?<a class="anchor-link" href="#What-data-is-good-data?-OR-What-do-you-mean-by-data-being-&quot;representative&quot;?">&#182;</a></h3><p>Let's look at this from first principles. Mathematically, the premise of machine learning (to be precise, the strand of machine learning we'll be working with here) is that given input variable X, and an output variable y, <strong>IF</strong> there is a function such that g(X)=y, then if g is unknown, we can "learn" a function f which approximates g. At the very heart, its not at all different from what you may have earlier studied as "curve fitting". For example, if you're trying to predict someone's movie preferences then X can be information about the person's gender, age, nationality and so on, while y can be the genre they most like to listen to!</p>
<p>Let's do a thought experiment. Consider the same example - I'm trying to predict people's movie preferences. I walk into a classroom today, and collect information about some students and their movie preferences. Now, I use that data to build a model. How well do you think I can predict my father's movie preferences? The answer is - probably not very well. Why? Intuitively, there was probably no one in the classroom who was my father's age. My model can tell me that as people go from age 18 to 30, they have a higher preference for documentaries over superhero movies. But does this trend continue at 55? Probably, they may start liking family dramas more. Probably they don't. In a nutshell, we cannot say with certainty, as our data tells us nothing about it. So, if the task was to make predictions about ANYONE's movie preferences, then the data collected from just undergraduates is NOT representative.</p>
<p>Now, let's see why this makes sense Mathematically. Look at the graph below.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><img src="contour.png"></p>
<center>Fig.1: Plot of a function we are trying to approximate(<a href="http://www.jzy3d.org/js/slider/images/ContourPlotsDemo.png">source</a>)</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>If we consider that the variable plotted on the vertical axis is $y$, and the values of the 2 variables on the horizontal axes make the input vector $X$, then, our hope is that we are able to find a function $f$ which can approximate the function plotted here. If all the data I collect is such that $x_1$ belongs to (80,100) and $x_2$ belongs to (80,100), the learned function will only be able to learn the "yellow-green dipping bellow" part of the function.  Our function will never be able to predict the behavior in the "red" regions of the true function. So, in order to be able to learn a good function, we need data sampled from a diverse set of values of $x_1$ and x2. That would be representative data to learn this contour.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Therefore, we want to collect data which is representative of all possible movies that we want to make predictions about. Or else (which is often the case), we need to be aware of the limitations of the model we have trained, and the predictions we can make with confidence. The easiest way to do this is to only make predictions about the domain of data we collected the training data from. For example, in our case, let us start by assuming that our model will predict genres for only English movies. Now, the task is to collect data about a diverse collection of movies.</p>
<p>So how do we get this data then? Neither google, nor any university has released such a dataset. We want to collect visual and textual data about these movies. The simple answer is to scrape it from the internet to build our own dataset. For the purpose of this project, we will use movie posters as our visual data, and movie plots as textual data. Using these, we will build a model that can predict movie genres!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="We-will-be-scraping-data-from-2-different-movie-sources---IMDB-and-TMDB">We will be scraping data from 2 different movie sources - IMDB and TMDB<a class="anchor-link" href="#We-will-be-scraping-data-from-2-different-movie-sources---IMDB-and-TMDB">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3>IMDB:http://www.imdb.com/</h3><p>For those unaware, IMDB is the primary source of information about movies on the internet. It is immensely rich with posters, reviews, synopsis, ratings and many other information on every movie. We will use this as our primary data source.</p>
<h3>TMDB:https://www.themoviedb.org/</h3><p>TMDB, or The Movie DataBase, is an open source version of IMDB, with a free to use API that can be used to collect information. You do need an API key, but it can be obtained for free by just making a request after making a free account.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h4 id="Note--">Note -<a class="anchor-link" href="#Note--">&#182;</a></h4><p>IMDB gives some information for free through the API, but doesn't release other information about movies. Here, we will keep it legal and only use information given to us for free and legally. However, scraping does reside on the moral fence, so to say. People often scrape data which isn't exactly publicly available for use from websites.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[2]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">urllib2</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">imdb</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">itertools</span>
<span class="kn">import</span> <span class="nn">wget</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">tmdbsimple</span> <span class="kn">as</span> <span class="nn">tmdb</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">matplotlib</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
<span class="o">%</span><span class="k">matplotlib</span> inline
<span class="kn">import</span> <span class="nn">seaborn</span> <span class="kn">as</span> <span class="nn">sns</span>
<span class="kn">import</span> <span class="nn">pickle</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Here-is-a-broad-outline-of-technical-steps-to-be-done-for-data-collection">Here is a broad outline of technical steps to be done for data collection<a class="anchor-link" href="#Here-is-a-broad-outline-of-technical-steps-to-be-done-for-data-collection">&#182;</a></h1><ul>
<li>Sign up for TMDB (themoviedatabase.org), and set up API to scrape movie posters for above movies.</li>
<li>Set up and work with TMDb to get movie information from their database</li>
<li>Do the same for IMDb</li>
<li>Compare the entries of IMDb and TMDb for a movie</li>
<li>Get a listing and information of a few movies</li>
<li>Think and ponder over the potential challenges that may come our way, and think about interesting questions we can answer given the API's we have in our hands.</li>
<li>Get data from the TMDb</li>
</ul>
<p>Let's go over each one of these one by one.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Signing-up-for-TMDB-and-getting-set-up-for-getting-movie-metadata.">Signing up for TMDB and getting set up for getting movie metadata.<a class="anchor-link" href="#Signing-up-for-TMDB-and-getting-set-up-for-getting-movie-metadata.">&#182;</a></h2><ul>
<li>Step 1. Head over to [tmdb.org] (<a href="https://www.themoviedb.org/?language=en">https://www.themoviedb.org/?language=en</a>) and create a new account there by signing up.</li>
<li>Step 2. Click on your account icon on the top right, then from drop down menu select "Settings".</li>
<li>Step 3. On the settings page, you will see the option "API" on the left pane. Click on that.</li>
<li>Step 4. Apply for a new developer key. Fill out the form as required. The fields "Application Name" and "Application URL" are not important. Fill anything there.</li>
<li>Step 5. It should generate a new API key for you and you should also receive a mail.</li>
</ul>
<p>Now that you have the API key for TMDB, you can query using TMDB. Remember, it allows only 40 queries per 10 seconds.</p>
<p>An easy way to respect this is to just have a call to <i>time.sleep(1)</i> after each iteration. This is also being very nice to the server.</p>
<p>If you want to try and maximize your throughput you can embed every TMDB request in a nested try except block. If the first try fails, the second try first uses python's sleep function to give it a little rest, and then try again to make a request. Something like this -</p>

<pre><code>try:
    search.movie(query=movie) #An API request
except:
    try:
        time.sleep(10) #sleep for a bit, to give API requests a rest.
        search.movie(query=&lt;i&gt;movie_name&lt;/i&gt;) #Make second API request
    except:
        print "Failed second attempt too, check if there's any error in request"</code></pre>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Using-TMDB-using-the-obtained-API-Key-to-get-movie-information">Using TMDB using the obtained API Key to get movie information<a class="anchor-link" href="#Using-TMDB-using-the-obtained-API-Key-to-get-movie-information">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>I have made these functions which make things easy. Basically, I'm making use of a library called tmdbsimple which makes TMDB using even easier. This library was installed at the time of setup.</p>
<p>However, if you  want to avoid the library, it is also easy enough to load the API output directly into a dictionary like this without using tmdbsimple:</p>

<pre><code>url = 'https://api.themoviedb.org/3/movie/1581?api_key=' + api_key
data = urllib2.urlopen(url).read()

# create dictionary from JSON 
dataDict = json.loads(data)</code></pre>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[5]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># set here the path where you want the scraped folders to be saved!</span>
<span class="n">poster_folder</span><span class="o">=</span><span class="s1">&#39;posters_final/&#39;</span>
<span class="k">if</span> <span class="n">poster_folder</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="s1">&#39;./&#39;</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Folder already exists&#39;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="s1">&#39;./&#39;</span><span class="o">+</span><span class="n">poster_folder</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Folder already exists
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[14]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">poster_folder</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[14]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&#39;posters_final/&#39;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[15]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># For the purpose of this example, i will be working with the 1999 Sci-Fi movie - &quot;The Matrix&quot;!</span>

<span class="n">api_key</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span> <span class="c1">#Enter your own API key here to run the code below. </span>
<span class="c1"># Generate your own API key as explained above :)</span>


<span class="n">tmdb</span><span class="o">.</span><span class="n">API_KEY</span> <span class="o">=</span> <span class="n">api_key</span> <span class="c1">#This sets the API key setting for the tmdb object</span>
<span class="n">search</span> <span class="o">=</span> <span class="n">tmdb</span><span class="o">.</span><span class="n">Search</span><span class="p">()</span> <span class="c1">#this instantiates a tmdb &quot;search&quot; object which allows your to search for the movie</span>

<span class="c1"># These functions take in a string movie name i.e. like &quot;The Matrix&quot; or &quot;Interstellar&quot;</span>
<span class="c1"># What they return is pretty much clear in the name - Poster, ID , Info or genre of the Movie!</span>
<span class="k">def</span> <span class="nf">grab_poster_tmdb</span><span class="p">(</span><span class="n">movie</span><span class="p">):</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">movie</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">movie</span><span class="p">)</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">response</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">movie</span> <span class="o">=</span> <span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
    <span class="n">posterp</span><span class="o">=</span><span class="n">movie</span><span class="o">.</span><span class="n">info</span><span class="p">()[</span><span class="s1">&#39;poster_path&#39;</span><span class="p">]</span>
    <span class="n">title</span><span class="o">=</span><span class="n">movie</span><span class="o">.</span><span class="n">info</span><span class="p">()[</span><span class="s1">&#39;original_title&#39;</span><span class="p">]</span>
    <span class="n">url</span><span class="o">=</span><span class="s1">&#39;image.tmdb.org/t/p/original&#39;</span><span class="o">+</span><span class="n">posterp</span>
    <span class="n">title</span><span class="o">=</span><span class="s1">&#39;_&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">title</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">))</span>
    <span class="n">strcmd</span><span class="o">=</span><span class="s1">&#39;wget -O &#39;</span><span class="o">+</span><span class="n">poster_folder</span><span class="o">+</span><span class="n">title</span><span class="o">+</span><span class="s1">&#39;.jpg &#39;</span><span class="o">+</span><span class="n">url</span>
    <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">strcmd</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">get_movie_id_tmdb</span><span class="p">(</span><span class="n">movie</span><span class="p">):</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">movie</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">movie</span><span class="p">)</span>
    <span class="n">movie_id</span><span class="o">=</span><span class="n">response</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">movie_id</span>

<span class="k">def</span> <span class="nf">get_movie_info_tmdb</span><span class="p">(</span><span class="n">movie</span><span class="p">):</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">movie</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">movie</span><span class="p">)</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">response</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">movie</span> <span class="o">=</span> <span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
    <span class="n">info</span><span class="o">=</span><span class="n">movie</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">info</span>

<span class="k">def</span> <span class="nf">get_movie_genres_tmdb</span><span class="p">(</span><span class="n">movie</span><span class="p">):</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">movie</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">movie</span><span class="p">)</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">response</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">movie</span> <span class="o">=</span> <span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
    <span class="n">genres</span><span class="o">=</span><span class="n">movie</span><span class="o">.</span><span class="n">info</span><span class="p">()[</span><span class="s1">&#39;genres&#39;</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">genres</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>While the above functions have been made to make it easy to get genres, posters and ID, all the information that can be accessed can be seen by calling the function get_movie_info() as shown below</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[16]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">get_movie_genres_tmdb</span><span class="p">(</span><span class="s2">&quot;The Matrix&quot;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>[{u&#39;id&#39;: 28, u&#39;name&#39;: u&#39;Action&#39;}, {u&#39;id&#39;: 878, u&#39;name&#39;: u&#39;Science Fiction&#39;}]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[17]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">info</span><span class="o">=</span><span class="n">get_movie_info_tmdb</span><span class="p">(</span><span class="s2">&quot;The Matrix&quot;</span><span class="p">)</span>
<span class="k">print</span> <span class="s2">&quot;All the Movie information from TMDB gets stored in a dictionary with the following keys for easy access -&quot;</span>
<span class="n">info</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>All the Movie information from TMDB gets stored in a dictionary with the following keys for easy access -
</pre>
</div>
</div>

<div class="output_area">
<div class="prompt output_prompt">Out[17]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>[u&#39;poster_path&#39;,
 u&#39;production_countries&#39;,
 u&#39;revenue&#39;,
 u&#39;overview&#39;,
 u&#39;video&#39;,
 u&#39;id&#39;,
 u&#39;genres&#39;,
 u&#39;title&#39;,
 u&#39;tagline&#39;,
 u&#39;vote_count&#39;,
 u&#39;homepage&#39;,
 u&#39;belongs_to_collection&#39;,
 u&#39;original_language&#39;,
 u&#39;status&#39;,
 u&#39;spoken_languages&#39;,
 u&#39;imdb_id&#39;,
 u&#39;adult&#39;,
 u&#39;backdrop_path&#39;,
 u&#39;production_companies&#39;,
 u&#39;release_date&#39;,
 u&#39;popularity&#39;,
 u&#39;original_title&#39;,
 u&#39;budget&#39;,
 u&#39;vote_average&#39;,
 u&#39;runtime&#39;]</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>So, to get the tagline of the movie we can use the above dictionary key -</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[18]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">info</span><span class="o">=</span><span class="n">get_movie_info_tmdb</span><span class="p">(</span><span class="s2">&quot;The Matrix&quot;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">info</span><span class="p">[</span><span class="s1">&#39;tagline&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Welcome to the Real World.
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Getting-movie-information-from-IMDB">Getting movie information from IMDB<a class="anchor-link" href="#Getting-movie-information-from-IMDB">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now that we know how to get information from TMDB, here's how we can get information about the same movie from IMDB. This makes it possible for us to combine more information, and get a richer dataset. I urge you to try and see what dataset you can make, and go above and beyond the basic things I've done in this tutorial. Due to the differences between the two datasets, you will have to do some cleaning, however both of these datasets are extremely clean and it will be minimal.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[19]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Create the IMDB object that will be used to access the IMDb&#39;s database.</span>
<span class="n">imbd_object</span> <span class="o">=</span> <span class="n">imdb</span><span class="o">.</span><span class="n">IMDb</span><span class="p">()</span> <span class="c1"># by default access the web.</span>

<span class="c1"># Search for a movie (get a list of Movie objects).</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">imbd_object</span><span class="o">.</span><span class="n">search_movie</span><span class="p">(</span><span class="s1">&#39;The Matrix&#39;</span><span class="p">)</span>

<span class="c1"># As this returns a list of all movies containing the word &quot;The Matrix&quot;, we pick the first element</span>
<span class="n">movie</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

<span class="n">imbd_object</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>

<span class="k">print</span> <span class="s2">&quot;All the information we can get about this movie from IMDB-&quot;</span>
<span class="n">movie</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>All the information we can get about this movie from IMDB-
</pre>
</div>
</div>

<div class="output_area">
<div class="prompt output_prompt">Out[19]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>[u&#39;music department&#39;,
 &#39;sound crew&#39;,
 &#39;camera and electrical department&#39;,
 u&#39;distributors&#39;,
 &#39;rating&#39;,
 &#39;runtimes&#39;,
 &#39;costume designer&#39;,
 &#39;make up&#39;,
 &#39;year&#39;,
 &#39;production design&#39;,
 &#39;miscellaneous crew&#39;,
 &#39;color info&#39;,
 u&#39;casting department&#39;,
 &#39;languages&#39;,
 &#39;votes&#39;,
 &#39;producer&#39;,
 &#39;title&#39;,
 &#39;mpaa&#39;,
 &#39;assistant director&#39;,
 &#39;writer&#39;,
 &#39;production manager&#39;,
 &#39;casting director&#39;,
 &#39;visual effects&#39;,
 &#39;top 250 rank&#39;,
 &#39;set decoration&#39;,
 &#39;editor&#39;,
 &#39;certificates&#39;,
 u&#39;costume department&#39;,
 &#39;country codes&#39;,
 &#39;language codes&#39;,
 &#39;cover url&#39;,
 u&#39;special effects department&#39;,
 &#39;special effects companies&#39;,
 &#39;sound mix&#39;,
 u&#39;location management&#39;,
 &#39;genres&#39;,
 &#39;director&#39;,
 &#39;stunt performer&#39;,
 &#39;miscellaneous companies&#39;,
 &#39;cinematographer&#39;,
 &#39;art direction&#39;,
 &#39;akas&#39;,
 &#39;aspect ratio&#39;,
 u&#39;production companies&#39;,
 &#39;kind&#39;,
 u&#39;art department&#39;,
 &#39;countries&#39;,
 u&#39;transportation department&#39;,
 &#39;plot outline&#39;,
 &#39;plot&#39;,
 &#39;cast&#39;,
 u&#39;animation department&#39;,
 &#39;original music&#39;,
 u&#39;editorial department&#39;,
 &#39;canonical title&#39;,
 &#39;long imdb title&#39;,
 &#39;long imdb canonical title&#39;,
 &#39;smart canonical title&#39;,
 &#39;smart long imdb canonical title&#39;,
 &#39;full-size cover url&#39;]</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[20]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="s2">&quot;The genres associated with the movie are - &quot;</span><span class="p">,</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;genres&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>The genres associated with the movie are -  [u&#39;Action&#39;, u&#39;Sci-Fi&#39;]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="A-small-comparison-of-IMDB-and-TMDB">A small comparison of IMDB and TMDB<a class="anchor-link" href="#A-small-comparison-of-IMDB-and-TMDB">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now that we have both systems running, let's do a very short comparison for the same movie?</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[21]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="s2">&quot;The genres for The Matrix pulled from IMDB are -&quot;</span><span class="p">,</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;genres&#39;</span><span class="p">]</span>
<span class="k">print</span> <span class="s2">&quot;The genres for The Matrix pulled from TMDB are -&quot;</span><span class="p">,</span><span class="n">get_movie_genres_tmdb</span><span class="p">(</span><span class="s2">&quot;The Matrix&quot;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>The genres for The Matrix pulled from IMDB are - [u&#39;Action&#39;, u&#39;Sci-Fi&#39;]
The genres for The Matrix pulled from TMDB are - [{u&#39;id&#39;: 28, u&#39;name&#39;: u&#39;Action&#39;}, {u&#39;id&#39;: 878, u&#39;name&#39;: u&#39;Science Fiction&#39;}]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As we can see, both the systems are correct, but the way they package information is different. TMDB calls it "Science Fiction" and has an ID for every genre. While IMDB calls it "Sci-Fi". Thus, it is important to keep track of these things when making use of both the datasets simultaneously.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now that we know how to scrape information for one movie, let's take a bigger step towards scraping multiple movies?</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Working-with-multiple-movies-:-Obtaining-Top-20-movies-from-TMDB">Working with multiple movies : Obtaining Top 20 movies from TMDB<a class="anchor-link" href="#Working-with-multiple-movies-:-Obtaining-Top-20-movies-from-TMDB">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>We first instantiate an object that inherits from class Movies from TMDB. Then We use the <strong>popular()</strong> class method (i.e. function) to get top movies. To get more than one page of results, the optional page argument lets us see movies from any specified page number.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[22]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">all_movies</span><span class="o">=</span><span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">()</span>
<span class="n">top_movies</span><span class="o">=</span><span class="n">all_movies</span><span class="o">.</span><span class="n">popular</span><span class="p">()</span>

<span class="c1"># This is a dictionary, and to access results we use the key &#39;results&#39; which returns info on 20 movies</span>
<span class="k">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">top_movies</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]))</span>
<span class="n">top20_movs</span><span class="o">=</span><span class="n">top_movies</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>20
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's look at one of these movies. It's the same format as above, as we had information on the movie "The Matrix", as you can see below. It's a dictionary which can be queried  for specific information on that movie</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[23]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">first_movie</span><span class="o">=</span><span class="n">top20_movs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">print</span> <span class="s2">&quot;Here is all the information you can get on this movie - &quot;</span>
<span class="k">print</span> <span class="n">first_movie</span>
<span class="k">print</span> <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">The title of the first movie is - &quot;</span><span class="p">,</span> <span class="n">first_movie</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Here is all the information you can get on this movie - 
{u&#39;poster_path&#39;: u&#39;/tWqifoYuwLETmmasnGHO7xBjEtt.jpg&#39;, u&#39;title&#39;: u&#39;Beauty and the Beast&#39;, u&#39;overview&#39;: u&#34;A live-action adaptation of Disney&#39;s version of the classic &#39;Beauty and the Beast&#39; tale of a cursed prince and a beautiful young woman who helps him break the spell.&#34;, u&#39;release_date&#39;: u&#39;2017-03-16&#39;, u&#39;popularity&#39;: 236.720585, u&#39;original_title&#39;: u&#39;Beauty and the Beast&#39;, u&#39;backdrop_path&#39;: u&#39;/6aUWe0GSl69wMTSWWexsorMIvwU.jpg&#39;, u&#39;vote_count&#39;: 3801, u&#39;video&#39;: False, u&#39;adult&#39;: False, u&#39;vote_average&#39;: 6.8, u&#39;genre_ids&#39;: [10751, 14, 10749], u&#39;id&#39;: 321612, u&#39;original_language&#39;: u&#39;en&#39;}


The title of the first movie is -  Beauty and the Beast
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's print out top 5 movie's titles!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[24]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">top20_movs</span><span class="p">)):</span>
    <span class="n">mov</span><span class="o">=</span><span class="n">top20_movs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">title</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
    <span class="k">print</span> <span class="n">title</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">==</span><span class="mi">4</span><span class="p">:</span>
        <span class="k">break</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Beauty and the Beast
Wonder Woman
Despicable Me 3
Spider-Man: Homecoming
Logan
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Yes,-I-know.-I'm-a-little-upset-too-seeing-Beauty-and-the-Beast-above-Logan-in-the-list!">Yes, I know. I'm a little upset too seeing Beauty and the Beast above Logan in the list!<a class="anchor-link" href="#Yes,-I-know.-I'm-a-little-upset-too-seeing-Beauty-and-the-Beast-above-Logan-in-the-list!">&#182;</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Moving on, we can get their genres the same way.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[25]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">top20_movs</span><span class="p">)):</span>
    <span class="n">mov</span><span class="o">=</span><span class="n">top20_movs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">genres</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
    <span class="k">print</span> <span class="n">genres</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">==</span><span class="mi">4</span><span class="p">:</span>
        <span class="k">break</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>[10751, 14, 10749]
[28, 12, 14]
[12, 16, 35, 10751]
[28, 12, 878]
[28, 18, 878]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>So, TMDB doesn't want to make your job as easy as you thought. Why these random numbers? Want to see their genre names? Well, there's the Genre() class for it. Let's get this done!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[26]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Create a tmdb genre object!</span>
<span class="n">genres</span><span class="o">=</span><span class="n">tmdb</span><span class="o">.</span><span class="n">Genres</span><span class="p">()</span>
<span class="c1"># the list() method of the Genres() class returns a listing of all genres in the form of a dictionary.</span>
<span class="n">list_of_genres</span><span class="o">=</span><span class="n">genres</span><span class="o">.</span><span class="n">list</span><span class="p">()[</span><span class="s1">&#39;genres&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's convert this list into a nice dictionary to look up genre names from genre IDs!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[27]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Genre_ID_to_name</span><span class="o">=</span><span class="p">{}</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">list_of_genres</span><span class="p">)):</span>
    <span class="n">genre_id</span><span class="o">=</span><span class="n">list_of_genres</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">genre_name</span><span class="o">=</span><span class="n">list_of_genres</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
    <span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_id</span><span class="p">]</span><span class="o">=</span><span class="n">genre_name</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now, let's re-print the genres of top 20 movies?</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[28]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">top20_movs</span><span class="p">)):</span>
    <span class="n">mov</span><span class="o">=</span><span class="n">top20_movs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">title</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
    <span class="n">genre_ids</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
    <span class="n">genre_names</span><span class="o">=</span><span class="p">[]</span>
    <span class="k">for</span> <span class="nb">id</span> <span class="ow">in</span> <span class="n">genre_ids</span><span class="p">:</span>
        <span class="n">genre_name</span><span class="o">=</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span>
        <span class="n">genre_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">genre_name</span><span class="p">)</span>
    <span class="k">print</span> <span class="n">title</span><span class="p">,</span><span class="n">genre_names</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">==</span><span class="mi">4</span><span class="p">:</span>
        <span class="k">break</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Beauty and the Beast [u&#39;Family&#39;, u&#39;Fantasy&#39;, u&#39;Romance&#39;]
Wonder Woman [u&#39;Action&#39;, u&#39;Adventure&#39;, u&#39;Fantasy&#39;]
Despicable Me 3 [u&#39;Adventure&#39;, u&#39;Animation&#39;, u&#39;Comedy&#39;, u&#39;Family&#39;]
Spider-Man: Homecoming [u&#39;Action&#39;, u&#39;Adventure&#39;, u&#39;Science Fiction&#39;]
Logan [u&#39;Action&#39;, u&#39;Drama&#39;, u&#39;Science Fiction&#39;]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-4---Building-a-dataset-to-work-with-:-Let's-take-a-look-at-the-top-1000-movies-from-the-database">Section 4 - Building a dataset to work with : Let's take a look at the top 1000 movies from the database<a class="anchor-link" href="#Section-4---Building-a-dataset-to-work-with-:-Let's-take-a-look-at-the-top-1000-movies-from-the-database">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Making use of the same api as before, we will just pull results from the top 50 pages. As mentioned earlier, the "page" attribute of the command top_movies=all_movies.popular() can be used for this purpose.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Please note: Some of the code below will store the data into python "pickle" files so that it can be ready directly from memory, as opposed to being downloaded every time. Once done, you should comment out any code which generated an object that was pickled and is no longer needed.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[29]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">all_movies</span><span class="o">=</span><span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">()</span>
<span class="n">top_movies</span><span class="o">=</span><span class="n">all_movies</span><span class="o">.</span><span class="n">popular</span><span class="p">()</span>

<span class="c1"># This is a dictionary, and to access results we use the key &#39;results&#39; which returns info on 20 movies</span>
<span class="nb">len</span><span class="p">(</span><span class="n">top_movies</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">])</span>
<span class="n">top20_movs</span><span class="o">=</span><span class="n">top_movies</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[30]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Comment out this cell once the data is saved into pickle file.</span>
<span class="n">all_movies</span><span class="o">=</span><span class="n">tmdb</span><span class="o">.</span><span class="n">Movies</span><span class="p">()</span>
<span class="n">top1000_movies</span><span class="o">=</span><span class="p">[]</span>
<span class="k">print</span><span class="p">(</span><span class="s1">&#39;Pulling movie list, Please wait...&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">51</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">15</span>==0:
        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
    <span class="n">movies_on_this_page</span><span class="o">=</span><span class="n">all_movies</span><span class="o">.</span><span class="n">popular</span><span class="p">(</span><span class="n">page</span><span class="o">=</span><span class="n">i</span><span class="p">)[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span>
    <span class="n">top1000_movies</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">movies_on_this_page</span><span class="p">)</span>
<span class="nb">len</span><span class="p">(</span><span class="n">top1000_movies</span><span class="p">)</span>
<span class="n">f3</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;movie_list.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">top1000_movies</span><span class="p">,</span><span class="n">f3</span><span class="p">)</span>
<span class="n">f3</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s1">&#39;Done!&#39;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[31]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f3</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;movie_list.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">top1000_movies</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f3</span><span class="p">)</span>
<span class="n">f3</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Pairwise-analysis-of-Movie-Genres">Pairwise analysis of Movie Genres<a class="anchor-link" href="#Pairwise-analysis-of-Movie-Genres">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As our dataset is multi label, simply looking at the ditribution of genres is not sufficient. It might be beneficial to see which genres co-occur, as it might shed some light on inherent biases in our dataset. For example, it would make sense if romance and comedy occur together more often than documentary and comedy. Such inherent biases tell us that the underlying population we are sampling from itself is skewed and not balanced. We may then take steps to account for such problems. Even if we don't take such steps, it is important to be aware that we are making the assumption that an unbalanced dataset is not hurting our performance and if need be, we can come back to address this assumption. Good old scientific method, eh?</p>
<p>So for the top 1000 movies let's do some pairwise analysis for genre distributions. Our main purpose is to see which genres occur together in the same movie. So, we first define a function which takes a list and makes all possible pairs from it. Then, we pull the list of genres for a movie and run this function on the list of genres to get all pairs of genres which occur together</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[32]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># This function just generates all possible pairs of movies</span>
<span class="k">def</span> <span class="nf">list2pairs</span><span class="p">(</span><span class="n">l</span><span class="p">):</span>
    <span class="c1"># itertools.combinations(l,2) makes all pairs of length 2 from list l.</span>
    <span class="n">pairs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
    <span class="c1"># then the one item pairs, as duplicate pairs aren&#39;t accounted for by itertools</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span>
        <span class="n">pairs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">i</span><span class="p">,</span><span class="n">i</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">pairs</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As mentioned, now we will pull genres for each movie, and use above function to count occurrences of when two genres occurred together</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[33]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># get all genre lists pairs from all movies</span>
<span class="n">allPairs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">movie</span> <span class="ow">in</span> <span class="n">top1000_movies</span><span class="p">:</span>
    <span class="n">allPairs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">list2pairs</span><span class="p">(</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]))</span>
    
<span class="n">nr_ids</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">allPairs</span><span class="p">)</span>
<span class="n">visGrid</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">nr_ids</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">nr_ids</span><span class="p">)))</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">allPairs</span><span class="p">:</span>
    <span class="n">visGrid</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">nr_ids</span><span class="o">==</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">nr_ids</span><span class="o">==</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])]</span><span class="o">+=</span><span class="mi">1</span>
    <span class="k">if</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
        <span class="n">visGrid</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">nr_ids</span><span class="o">==</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">nr_ids</span><span class="o">==</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">])]</span><span class="o">+=</span><span class="mi">1</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's take a look at the structure we just made. It is a 19X19 structure, as shown below. Also, see that we had 19 Genres. Needless to say, this structure counts the number of simultaneous occurrences of genres in same movie.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[34]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">visGrid</span><span class="o">.</span><span class="n">shape</span>
<span class="k">print</span> <span class="nb">len</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>(19, 19)
19
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[35]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">annot_lookup</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">nr_ids</span><span class="p">)):</span>
    <span class="n">annot_lookup</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">nr_ids</span><span class="p">[</span><span class="n">i</span><span class="p">]])</span>

<span class="n">sns</span><span class="o">.</span><span class="n">heatmap</span><span class="p">(</span><span class="n">visGrid</span><span class="p">,</span> <span class="n">xticklabels</span><span class="o">=</span><span class="n">annot_lookup</span><span class="p">,</span> <span class="n">yticklabels</span><span class="o">=</span><span class="n">annot_lookup</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[35]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&lt;matplotlib.axes._subplots.AxesSubplot at 0x111aa6290&gt;</pre>
</div>

</div>

<div class="output_area">
<div class="prompt"></div>



<div class="output_png output_subarea ">
<img src="
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
AAAASUVORK5CYII=
"
>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The above image shows how often the genres occur together, as a heatmap</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Important thing to notice in the above plot is the diagonal. The diagonal corresponds to self-pairs, i.e. number of times a genre, say Drama occurred with Drama. Which is basically just a count of the total times that genre occurred!</p>
<p>As we can see there are a lot of dramas in the data set, it is also a very unspecific label. There are nearly no documentaries or TV Movies. Horror is a very distinct label, and romance is also not too widely spread.</p>
<p>To account for this unbalanced data, there are multiple things we can try to explore what interesting relationships can be found.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Delving-Deeper-into-co-occurrence-of-genres">Delving Deeper into co-occurrence of genres<a class="anchor-link" href="#Delving-Deeper-into-co-occurrence-of-genres">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>What we want to do now is to look for nice groups of genres that co-occur, and see if it makes sense to us logically? Intuitively speaking, wouldn't it be fun if we saw nice boxes on the above plot - boxes of high intensity i.e. genres that occur together and don't occur much with other genres. In some ways, that would isolate the co-occurrence of some genres, and heighten the co-occurrence of others.</p>
<p>While the data may not show that directly, we can play with the numbers to see if that's possible. The technique used for that is called biclustering.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[36]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.cluster</span> <span class="kn">import</span> <span class="n">SpectralCoclustering</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[37]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">model</span> <span class="o">=</span> <span class="n">SpectralCoclustering</span><span class="p">(</span><span class="n">n_clusters</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">visGrid</span><span class="p">)</span>

<span class="n">fit_data</span> <span class="o">=</span> <span class="n">visGrid</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">row_labels_</span><span class="p">)]</span>
<span class="n">fit_data</span> <span class="o">=</span> <span class="n">fit_data</span><span class="p">[:,</span> <span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">column_labels_</span><span class="p">)]</span>

<span class="n">annot_lookup_sorted</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">row_labels_</span><span class="p">):</span>
    <span class="n">annot_lookup_sorted</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">nr_ids</span><span class="p">[</span><span class="n">i</span><span class="p">]])</span>
    
<span class="n">sns</span><span class="o">.</span><span class="n">heatmap</span><span class="p">(</span><span class="n">fit_data</span><span class="p">,</span> <span class="n">xticklabels</span><span class="o">=</span><span class="n">annot_lookup_sorted</span><span class="p">,</span> <span class="n">yticklabels</span><span class="o">=</span><span class="n">annot_lookup_sorted</span><span class="p">,</span> <span class="n">annot</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s2">&quot;After biclustering; rearranged to show biclusters&quot;</span><span class="p">)</span>

<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>



<div class="output_png output_subarea ">
<img src="
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
"
>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Looking at the above figure, "boxes" or groups of movie genres automatically emerge!</p>
<p>Intuitively - Crime, Sci-Fi, Mystery, Action, Horror, Drama, Thriller, etc co-occur. 
AND, Romance, Fantasy, Family, Music, Adventure, etc co-occur.</p>
<p>That makes a lot of intuitive sense, right?</p>
<p>One challenge is the broad range of the drama genre. It makes the two clusters highly overlapping. If we merge it together with action thriller, etc. We will end up with nearly all movies just having that label.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><strong>Based on playing around with the stuff above, we can sort the data into the following genre categories - "Drama, Action, ScienceFiction, exciting(thriller, crime, mystery), uplifting(adventure, fantasy, animation, comedy, romance, family), Horror, History"</strong></p>
<p>Note: that this categorization is subjective and by no means the only right solution. One could also just stay with the original labels and only exclude the ones with not enough data. Such tricks are important to balance the dataset, it allows us to increase or decrease the strength of certain signals, making it possible to improve our inferences :)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Interesting-Questions">Interesting Questions<a class="anchor-link" href="#Interesting-Questions">&#182;</a></h1><p>This really should be a place for you to get creative and hopefully come up with better questions than me.</p>
<p>Here are some of my thoughts:</p>
<ul>
<li>Which actors are bound to a genre, and which can easily hop genres?</li>
<li>Is there a trend in genre popularity over the years?</li>
<li>Can you use sound tracks to identify the genre of a movie?</li>
<li>Are top romance actors higher paid than top action actors?</li>
<li>If you look at release date vs popularity score, which movie genres have a longer shelf life?</li>
</ul>
<p>Ideas to explore specifically for feature correlations:</p>
<ul>
<li>Are title length correlated with movie genre?</li>
<li>Are movie posters darker for horror than for romance end comedy?</li>
<li>Are some genres specifically released more often at a certain time of year? </li>
<li>Is the RPG rating correlated with the genre?</li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Based-on-this-new-category-set,-we-will-now-pull-posters-from-TMDB-as-our-training-data!">Based on this new category set, we will now pull posters from TMDB as our training data!<a class="anchor-link" href="#Based-on-this-new-category-set,-we-will-now-pull-posters-from-TMDB-as-our-training-data!">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[41]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Done before, reading from pickle file now to maintain consistency of data!</span>
<span class="c1"># We now sample 100 movies per genre. Problem is that the sorting is by popular movies, so they will overlap. </span>
<span class="c1"># Need to exclude movies that were already sampled. </span>
<span class="n">movies</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">baseyear</span> <span class="o">=</span> <span class="mi">2017</span>

<span class="k">print</span><span class="p">(</span><span class="s1">&#39;Starting pulling movies from TMDB. If you want to debug, uncomment the print command. This will take a while, please wait...&#39;</span><span class="p">)</span>
<span class="n">done_ids</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">g_id</span> <span class="ow">in</span> <span class="n">nr_ids</span><span class="p">:</span>
    <span class="c1">#print(&#39;Pulling movies for genre ID &#39;+g_id)</span>
    <span class="n">baseyear</span> <span class="o">-=</span> <span class="mi">1</span>
    <span class="k">for</span> <span class="n">page</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">1</span><span class="p">):</span>
        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
    
        <span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;https://api.themoviedb.org/3/discover/movie?api_key=&#39;</span> <span class="o">+</span> <span class="n">api_key</span>
        <span class="n">url</span> <span class="o">+=</span> <span class="s1">&#39;&amp;language=en-US&amp;sort_by=popularity.desc&amp;year=&#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">baseyear</span><span class="p">)</span> 
        <span class="n">url</span> <span class="o">+=</span> <span class="s1">&#39;&amp;with_genres=&#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">g_id</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;&amp;page=&#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">page</span><span class="p">)</span>

        <span class="n">data</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>

        <span class="n">dataDict</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
        <span class="n">movies</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">dataDict</span><span class="p">[</span><span class="s2">&quot;results&quot;</span><span class="p">])</span>
    <span class="n">done_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">g_id</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="s2">&quot;Pulled movies for genres - &quot;</span><span class="o">+</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">done_ids</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Starting pulling movies from TMDB. If you want to debug, uncomment the print command. This will take a while, please wait...
Pulled movies for genres - 12
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[42]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># f6=open(&quot;movies_for_posters&quot;,&#39;wb&#39;)</span>
<span class="c1"># pickle.dump(movies,f6)</span>
<span class="c1"># f6.close()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[43]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f6</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s2">&quot;movies_for_posters&quot;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">movies</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f6</span><span class="p">)</span>
<span class="n">f6</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's remove any duplicates that we have in the list of movies</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[44]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">movie_ids</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">movies</span><span class="p">]</span>
<span class="k">print</span> <span class="s2">&quot;originally we had &quot;</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">movie_ids</span><span class="p">),</span><span class="s2">&quot; movies&quot;</span>
<span class="n">movie_ids</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">movie_ids</span><span class="p">)</span>
<span class="k">print</span> <span class="nb">len</span><span class="p">(</span><span class="n">movie_ids</span><span class="p">)</span>
<span class="n">seen_before</span><span class="o">=</span><span class="p">[]</span>
<span class="n">no_duplicate_movies</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">movies</span><span class="p">)):</span>
    <span class="n">movie</span><span class="o">=</span><span class="n">movies</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="k">if</span> <span class="nb">id</span> <span class="ow">in</span> <span class="n">seen_before</span><span class="p">:</span>
        <span class="k">continue</span>
<span class="c1">#         print &quot;Seen before&quot;</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">seen_before</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
        <span class="n">no_duplicate_movies</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
<span class="k">print</span> <span class="s2">&quot;After removing duplicates we have &quot;</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">no_duplicate_movies</span><span class="p">),</span> <span class="s2">&quot; movies&quot;</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>originally we had  1670  movies
1608
After removing duplicates we have  1608  movies
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Also, let's remove movies for which we have no posters!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[45]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">poster_movies</span><span class="o">=</span><span class="p">[]</span>
<span class="n">counter</span><span class="o">=</span><span class="mi">0</span>
<span class="n">movies_no_poster</span><span class="o">=</span><span class="p">[]</span>
<span class="k">print</span><span class="p">(</span><span class="s2">&quot;Total movies : &quot;</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">movies</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="s2">&quot;Started downloading posters...&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">movie</span> <span class="ow">in</span> <span class="n">movies</span><span class="p">:</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">title</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
    <span class="k">if</span> <span class="n">counter</span><span class="o">==</span><span class="mi">1</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Downloaded first. Code is working fine. Please wait, this will take quite some time...&#39;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">counter</span><span class="o">%</span><span class="k">300</span>==0 and counter!=0:
        <span class="k">print</span> <span class="s2">&quot;Done with &quot;</span><span class="p">,</span><span class="n">counter</span><span class="p">,</span><span class="s2">&quot; movies!&quot;</span>
        <span class="k">print</span> <span class="s2">&quot;Trying to get poster for &quot;</span><span class="p">,</span><span class="n">title</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">grab_poster_tmdb</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
        <span class="n">poster_movies</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
    <span class="k">except</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
            <span class="n">grab_poster_tmdb</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
            <span class="n">poster_movies</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="n">movies_no_poster</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
    <span class="n">counter</span><span class="o">+=</span><span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="s2">&quot;Done with all the posters!&quot;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>(&#39;Total movies : &#39;, 1670)
Started downloading posters...
Downloaded first. Code is working fine. Please wait, this will take quite some time...
Done with  300  movies!
Trying to get poster for  Gravity
Done with  600  movies!
Trying to get poster for  Zombieland
Done with  900  movies!
Trying to get poster for  The Substitute
Done with  1200  movies!
Trying to get poster for  Decoys
Done with  1500  movies!
Trying to get poster for  Lost and Delirious
Done with all the posters!
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[46]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="nb">len</span><span class="p">(</span><span class="n">movies_no_poster</span><span class="p">)</span>
<span class="k">print</span> <span class="nb">len</span><span class="p">(</span><span class="n">poster_movies</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>170
1500
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[47]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># f=open(&#39;poster_movies.pckl&#39;,&#39;w&#39;)</span>
<span class="c1"># pickle.dump(poster_movies,f)</span>
<span class="c1"># f.close()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[48]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;poster_movies.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;r&#39;</span><span class="p">)</span>
<span class="n">poster_movies</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[49]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># f=open(&#39;no_poster_movies.pckl&#39;,&#39;w&#39;)</span>
<span class="c1"># pickle.dump(movies_no_poster,f)</span>
<span class="c1"># f.close()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[50]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;no_poster_movies.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;r&#39;</span><span class="p">)</span>
<span class="n">movies_no_poster</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Congratulations,-we-are-done-scraping!">Congratulations, we are done scraping!<a class="anchor-link" href="#Congratulations,-we-are-done-scraping!">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Building-a-dataset-out-of-the-scraped-information!">Building a dataset out of the scraped information!<a class="anchor-link" href="#Building-a-dataset-out-of-the-scraped-information!">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>This task is simple, but <strong>extremely</strong> important. It's basically what will set the stage for the whole project. Given that you have the freedom to cast their own project within the framework I am providing, there are many decisions that you must make to finalize <strong>your own version</strong> of the project.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As we are working on a <strong>classification</strong> problem, we need to make two decisions given the data at hand -</p>
<ul>
<li>What do we want to predict, i.e. what's our Y?</li>
<li>What features to use for predicting this Y, i.e. what X should we use?</li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>There are many different options possible, and it comes down to you to decide what's most exciting. I will be picking my own version for the example, <strong>but it is imperative that you think this through, and come up with a version which excites you!</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As an example, here are some possible ways to frame Y, while still sticking to the problem of genre prediction -</p>
<ul>
<li><p>Assume every movie can have multiple genres, and then it becomes a multi-label classification problem. For example, a movie can be Action, Horror and Adventure simultaneously. Thus, every movie can be more than one genre.</p>
</li>
<li><p>Make clusters of genres as we did in Milestone 1 using biclustering, and then every movie can have only 1 genre. This way, the problem becomes a simpler, multi-class problem. For example, a movie could have the class - Uplifting (refer Milestone 1), or Horror or History. No movie get's more than one class.</p>
</li>
</ul>
<p>For the purposes of this implementation, I'm going with the first case explained above - i.e. a multi-label classification problem.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Similarly, for designing our input features i.e. X, you may pick any features you think make sense, for example, the Director of a movie may be a good predictor for genre. OR, they may choose any features they design using algorithms like PCA. Given the richness of IMDB, TMDB and alternate sources like Wikipedia, there is a plethora of options available. <strong>Be creative here!</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Another important thing to note is that in doing so, we must also make many more small implementation decisions on the way. For example, what genres are we going to include? what movies are we going to include? All these are open ended!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="My-Implementation">My Implementation<a class="anchor-link" href="#My-Implementation">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Implementation decisions made -</p>
<ul>
<li>The problem is framed here as a multi-label problem explained above. </li>
<li>We will try to predict multiple genres associated with a movie. This will be our Y.</li>
<li>We will use 2 different kinds of X - text and images. </li>
<li>For the text part - Input features being used to predict the genre is a form of the movie's plot available from TMDB using the property 'overview'. This will be our X.</li>
<li>For the image part - we will use the scraped poster images as our X. </li>
</ul>
<p>NOTE : We will first look at some conventional machine learning models, which were popular before the recent rise of neural networks and deep learning. For the poster image to genre prediction, I have avoided using this for the reason that conventional ML models are simply not used anymore without using deep learning for feature extraction (all discussed in detail ahead, don't be scared by the jargon). For the movie overview to genre prediction problem we will look at both conventional models and deep learning models.</p>
<p>Now, let's build our X and Y!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>First, let's identify movies that have overviews. <strong>Next few steps are going to be a good example on why data cleaning is important!</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[51]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">movies_with_overviews</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">no_duplicate_movies</span><span class="p">)):</span>
    <span class="n">movie</span><span class="o">=</span><span class="n">no_duplicate_movies</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">overview</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;overview&#39;</span><span class="p">]</span>
    
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">overview</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
        <span class="k">continue</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">movies_with_overviews</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
        
<span class="nb">len</span><span class="p">(</span><span class="n">movies_with_overviews</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[51]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>1595</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now let's store the genre's for these movies in a list that we will later transform into a binarized vector.</p>
<p>Binarized vector representation is a very common and important way data is stored/represented in ML. Essentially, it's a way to reduce a categorical variable with n possible values to n binary indicator variables. What does that mean? For example, let [(1,3),(4)] be the list saying that sample A has two labels 1 and 3, and sample B has one label 4. For every sample, for every possible label, the representation is simply 1 if it has that label, and 0 if it doesn't have that label. So the binarized version of the above list will be -</p>

<pre><code>[(1,0,1,0]),
(0,0,0,1])]</code></pre>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[52]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># genres=np.zeros((len(top1000_movies),3))</span>
<span class="n">genres</span><span class="o">=</span><span class="p">[]</span>
<span class="n">all_ids</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">movies_with_overviews</span><span class="p">)):</span>
    <span class="n">movie</span><span class="o">=</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">genre_ids</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
    <span class="n">genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">genre_ids</span><span class="p">)</span>
    <span class="n">all_ids</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">genre_ids</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[53]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">MultiLabelBinarizer</span>
<span class="n">mlb</span><span class="o">=</span><span class="n">MultiLabelBinarizer</span><span class="p">()</span>
<span class="n">Y</span><span class="o">=</span><span class="n">mlb</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[54]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">genres</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[54]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>[28, 12, 35, 10749]</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[55]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">Y</span><span class="o">.</span><span class="n">shape</span>
<span class="k">print</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>(1595, 20)
[327 234 220 645 222 438 404 138  45 440 233 133 242 196 135 232 256  80
  23  25]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[62]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">list_of_genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[62]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>19</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>This is interesting. We started with only 19 genre labels if you remember. But the shape for Y is 1666,20 while it should be 1666,19 as there are only 19 genres? Let's explore.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's find genre IDs that are not present in our original list of genres!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[63]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Create a tmdb genre object!</span>
<span class="n">genres</span><span class="o">=</span><span class="n">tmdb</span><span class="o">.</span><span class="n">Genres</span><span class="p">()</span>
<span class="c1"># the list() method of the Genres() class returns a listing of all genres in the form of a dictionary.</span>
<span class="n">list_of_genres</span><span class="o">=</span><span class="n">genres</span><span class="o">.</span><span class="n">list</span><span class="p">()[</span><span class="s1">&#39;genres&#39;</span><span class="p">]</span>
<span class="n">Genre_ID_to_name</span><span class="o">=</span><span class="p">{}</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">list_of_genres</span><span class="p">)):</span>
    <span class="n">genre_id</span><span class="o">=</span><span class="n">list_of_genres</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">genre_name</span><span class="o">=</span><span class="n">list_of_genres</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
    <span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_id</span><span class="p">]</span><span class="o">=</span><span class="n">genre_name</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[64]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">all_ids</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">i</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Genre_ID_to_name</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
        <span class="k">print</span> <span class="n">i</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>10769
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Well, this genre ID wasn't given to us by TMDB when we asked it for all possible genres. How do we go about this now? We can either neglect all samples that have this genre. But if you look up you'll see there's too many of these samples. So, I googled more and went into their documentation and found that this ID corresponds to the genre "Foreign". So, we add it to the dictionary of genre names ourselves. Such problems are ubiquitous in machine learning, and it is up to us to diagnose and correct them. We must always make a decision about what to keep, how to store data and so on.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[65]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="mi">10769</span><span class="p">]</span><span class="o">=</span><span class="s2">&quot;Foreign&quot;</span> <span class="c1">#Adding it to the dictionary</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[66]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[66]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>20</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now, we turn to building the X matrix i.e. the input features! As described earlier, we will be using the overview of movies as our input vector! Let's look at a movie's overview for example!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[67]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">sample_movie</span><span class="o">=</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
<span class="n">sample_overview</span><span class="o">=</span><span class="n">sample_movie</span><span class="p">[</span><span class="s1">&#39;overview&#39;</span><span class="p">]</span>
<span class="n">sample_title</span><span class="o">=</span><span class="n">sample_movie</span><span class="p">[</span><span class="s1">&#39;title&#39;</span><span class="p">]</span>
<span class="k">print</span> <span class="s2">&quot;The overview for the movie&quot;</span><span class="p">,</span><span class="n">sample_title</span><span class="p">,</span><span class="s2">&quot; is - </span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="k">print</span> <span class="n">sample_overview</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>The overview for the movie Doctor Strange  is - 


After his career is destroyed, a brilliant but arrogant surgeon gets a new lease on life when a sorcerer takes him under his wing and trains him to defend the world against evil.
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="So,-how-do-we-store-this-movie-overview-in-a-matrix?">So, how do we store this movie overview in a matrix?<a class="anchor-link" href="#So,-how-do-we-store-this-movie-overview-in-a-matrix?">&#182;</a></h2><h4 id="Do-we-just-store-the-whole-string?-We-know-that-we-need-to-work-with-numbers,-but-this-is-all-text.-What-do-we-do?!">Do we just store the whole string? We know that we need to work with numbers, but this is all text. What do we do?!<a class="anchor-link" href="#Do-we-just-store-the-whole-string?-We-know-that-we-need-to-work-with-numbers,-but-this-is-all-text.-What-do-we-do?!">&#182;</a></h4>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The way we will be storing the X matrix is called a "Bag of words" representation. The basic idea of this representation in our context is that we can think of all the distinct words that are possible in the movies' reviews as a distinct object. And then every movie overview can be thought as a "Bag" containing a bunch of these possible objects.</p>
<p>For example, in the case of Zootopia the movie above - The "Bag" contains the words ("Determined", "to", "prove", "herself"......"the", "mystery"). We make such lists for all movie overviews. Finally, we binarize again like we did above for Y. scikit-learn makes our job easy here by simply using a function CountVectorizer() because this representation is so often used in Machine Learning.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>What this means is that, for all the movies that we have the data on, we will first count all the unique words. Say, there's 30,000 unique words. Then we can represent every movie overview as a 30000x1 vector, where each position in the vector corresponds to the presence or absence of a particular word. If the word corresponding to that position is present in the overview, that position will have 1, otherwise it will be 0.</p>
<p>Ex - if our vocabular was 4 words - "I","am","a","good","boy", then the representation for the sentence "I am a boy" would be [1 1 1 0 1], and for the sentence "I am good" would be [1 1 0 1 0].</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[68]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.feature_extraction.text</span> <span class="kn">import</span> <span class="n">CountVectorizer</span>
<span class="kn">import</span> <span class="nn">re</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[69]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">content</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">movies_with_overviews</span><span class="p">)):</span>
    <span class="n">movie</span><span class="o">=</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="nb">id</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span>
    <span class="n">overview</span><span class="o">=</span><span class="n">movie</span><span class="p">[</span><span class="s1">&#39;overview&#39;</span><span class="p">]</span>
    <span class="n">overview</span><span class="o">=</span><span class="n">overview</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
    <span class="n">overview</span><span class="o">=</span><span class="n">overview</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
    <span class="n">content</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">overview</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[70]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">content</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">print</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>A teenager finds himself transported to an island where he must help protect a group of orphans with special powers from creatures intent on destroying them
1595
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Are-all-words-equally-important?">Are all words equally important?<a class="anchor-link" href="#Are-all-words-equally-important?">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h4 id="At-the-cost-of-sounding-&quot;Animal-Farm&quot;-inspired,-I-would-say-not-all-words-are-equally-important.">At the cost of sounding "Animal Farm" inspired, I would say not all words are equally important.<a class="anchor-link" href="#At-the-cost-of-sounding-&quot;Animal-Farm&quot;-inspired,-I-would-say-not-all-words-are-equally-important.">&#182;</a></h4><p>For example, let's consider the overview for the Matrix -</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[75]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">get_movie_info_tmdb</span><span class="p">(</span><span class="s1">&#39;The Matrix&#39;</span><span class="p">)[</span><span class="s1">&#39;overview&#39;</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[75]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>u&#39;Set in the 22nd century, The Matrix tells the story of a computer hacker who joins a group of underground insurgents fighting the vast and powerful computers who now rule the earth.&#39;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For "The Matrix" a word like "computer" is a stronger indicators of it being a Sci-Fi movie, than words like "who" or "powerful" or "vast". One way computer scientists working with natural language tackled this problem in the past (and it is still used very popularly) is what we call TF-IDF i.e. Term Frequence, Inverse Document Frequency. The basic idea here is that words that are strongly indicative of the content of a single document (every movie overview is a document in our case) are words that occur very frequently in that document, and very infrequently in all other documents. For example, "Computer" occurs twice here but probably will not in most other movie overviews. Hence, it is indicative. On the other hand, generic words like "a","and","the" will occur very often in all documents. Hence, they are not indicative.</p>
<p>So, can we use this information to reduce our insanely high 30,000 dimensional vector representation to a smaller, more handle-able number? But first up, why should we even care? The answer is probably one of the most used phrases in ML - "The Curse of Dimensionality".</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="The-Curse-of-Dimensionality">The Curse of Dimensionality<a class="anchor-link" href="#The-Curse-of-Dimensionality">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h4 id="This-section-is-strongly-borrowing-from-one-of-the-greatest-ML-papers-I've-ever-read.">This section is strongly borrowing from one of the greatest <a href="https://homes.cs.washington.edu/~pedrod/papers/cacm12.pdf">ML papers I've ever read.</a><a class="anchor-link" href="#This-section-is-strongly-borrowing-from-one-of-the-greatest-ML-papers-I've-ever-read.">&#182;</a></h4><p>This expression was coined by Bellman in 1961 to refer to the fact that many algorithms that work fine in low dimensions become intractable when the input is high-dimensional. The reason for them not working in high dimensions is very strongly linked to what we discussed earlier - having a representative dataset. Consider this, you have a function $f$ dependent only one dependent variable $x$, and $x$ can only integer values from 1 to 100. Since it's one dimensional, it can be plotted on a line. To get a representative sample, you'd need to sample something like - $f(1),f(20),f(40),f(60),f(80),f(100)$</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now, let's increase the dimensionality i.e. number of dependent variables and see what happens. Say, we have 2 variables $x_1$ and $x_2$, same possible as before - integers between 1 and 100. Now, instead of a line, we'll have a plane with $x_1$ and $x_2$ on the two axes. The interesting bit is that instead of 100 possible values of dependent variables like before, we now have 100,000 possible values! Basically, we can make 100x100 table of possible values of $x_1$ and $x_2$. Wow, that increased exponentially. Not just figuratively, but mathematically exponentially. Needless to say, to cover 5% of the space like we did before, we'd need to sample $f$ at 5000 values.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For 3 variables, it would be 100,000,000, and we'd need to sample at 500,000 points. That's already more than the number of data points we have for most training problems we will ever come across.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Basically, as the dimensionality (number of features) of the examples grows, because a fixed-size training set covers a dwindling fraction of the input space. Even with a moderate dimension of 100 and a huge training set of a trillion examples, the latter covers only a fraction of about $10^{−18}$ of the input space. This is what makes machine learning
both necessary and hard.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>So, yes, if some words are unimportant, we want to get rid of them and reduce the dimensionality of our X matrix. And the way we will do it is using TF-IDF to identify un-important words. Python let's us do this with just one line of code (And this is why you should spend more time reading maths, than coding!)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[76]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># The min_df paramter makes sure we exclude words that only occur very rarely</span>
<span class="c1"># The default also is to exclude any words that occur in every movie description</span>
<span class="n">vectorize</span><span class="o">=</span><span class="n">CountVectorizer</span><span class="p">(</span><span class="n">max_df</span><span class="o">=</span><span class="mf">0.95</span><span class="p">,</span> <span class="n">min_df</span><span class="o">=</span><span class="mf">0.005</span><span class="p">)</span>
<span class="n">X</span><span class="o">=</span><span class="n">vectorize</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>We are excluding all words that occur in too many or too few documents, as these are very unlikely to be discriminative. Words that only occur in one document most probably are names, and words that occur in nearly all documents are probably stop words. Note that the values here were not tuned using a validation set. They are just guesses. It is ok to do, because we didn't evaluate the performance of these parameters. In a strict case, for example for a publication, it would be better to tune these as well.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[77]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[77]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1595, 1365)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>So, each movie's overview gets represented by a 1x1365 dimensional vector.</p>
<p>Now, we are ready for the kill. Our data is cleaned, hypothesis is set (Overview can predict movie genre), and the feature/output vectors are prepped. Let's train some models!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[78]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="n">f4</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;X.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">f5</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;Y.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">f4</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span><span class="n">f5</span><span class="p">)</span>
<span class="n">f6</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;Genredict.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">,</span><span class="n">f6</span><span class="p">)</span>
<span class="n">f4</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">f5</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">f6</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Congratulations,-we-have-our-data-set-ready!">Congratulations, we have our data set ready!<a class="anchor-link" href="#Congratulations,-we-have-our-data-set-ready!">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>A note : As we are building our own dataset, and I didn't want you to spend all your time waiting for poster image downloads to finish, I am working with an EXTREMELY small dataset. That is why, the results we will see for the deep learning portion will not be spectacular as compared to conventional machine learning methods. If you want to see the real power, you should spend some more time scraping something of the order of 100,000 images, as opposed to 1000 odd like I am doing here. Quoting the paper I mentioned above -  MORE DATA BEATS A CLEVERER ALGORITHM.</p>
<h4 id="As-the-TA,-I-saw-that-most-teams-working-on-the-project-had-data-of-the-order-of-100,000-movies.-So,-if-you-want-to-extract-the-power-of-these-models,-consider-scraping-a-larger-dataset-than-me.">As the TA, I saw that most teams working on the project had data of the order of 100,000 movies. So, if you want to extract the power of these models, consider scraping a larger dataset than me.<a class="anchor-link" href="#As-the-TA,-I-saw-that-most-teams-working-on-the-project-had-data-of-the-order-of-100,000-movies.-So,-if-you-want-to-extract-the-power-of-these-models,-consider-scraping-a-larger-dataset-than-me.">&#182;</a></h4>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-5---Non-deep,-Conventional-ML-models-with-above-data">Section 5 - Non-deep, Conventional ML models with above data<a class="anchor-link" href="#Section-5---Non-deep,-Conventional-ML-models-with-above-data">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Here is a layout of what we will be doing -</p>
<ul>
<li>We will implement two different models</li>
<li>We will decide a performance metric i.e. a quantitative method to be sure about how well difference models are doing. </li>
<li>Discussion of the differences between the models, their strengths, weaknesses, etc. </li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As discussed earlier, there are a LOT of implementation decisions to be made. Between feature engineering, hyper-parameter tuning, model selection and how interpretable do you want your model to be (Read : Bayesian vs Non-Bayesian approaches) a lot is to be decided. For example, some of these models could be:</p>
<ul>
<li>Generalized Linear Models</li>
<li>SVM</li>
<li>Shallow (1 Layer, i.e. not deep) Neural Network</li>
<li>Random Forest</li>
<li>Boosting</li>
<li>Decision Tree</li>
</ul>
<p>Or go more bayesian:</p>
<ul>
<li>Naive Bayes</li>
<li>Linear or Quadratic Discriminant Analysis</li>
<li>Bayesian Hierarchical models</li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The list is endless, and not all models will make sense for the kind of problem you have framed for yourself. <strong> Think about which model best fits for your purpose.</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For our purposes here, I will be showing the example of 2 very simple models, one picked from each category above -</p>
<ol>
<li>SVM</li>
<li>Multinomial Naive Bayes</li>
</ol>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>A quick overview of the whole pipeline coming below:</p>
<ul>
<li>A little bit of feature engineering</li>
<li>2 different Models </li>
<li>Evaluation Metrics chosen</li>
<li>Model comparisons</li>
</ul>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Let's-start-with-some-feature-engineering.">Let's start with some feature engineering.<a class="anchor-link" href="#Let's-start-with-some-feature-engineering.">&#182;</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Engineering the right features depends on 2 key ideas. Firstly, what is it that you are trying to solve? For example, if you want to guess my music preferences and you try to train a super awesome model while giving it what my height is as input features, you're going to have no luck. On the other hand, giving it my Spotify playlist will solve the problem with any model. So, CONTEXT of the problem plays a role.</p>
<p>Second, you can only represent based on the data at hand. Meaning, if you didn't have access to my Spotify playlist, but to my Facebook statuses - You know all my statuses about Harvard may not be useful. But if you represent me as my Facebook statuses which are YouTube links, that would also solve the problem. So, AVAILABILITY OF DATA at hand is the second factor.</p>
<h4 id="A-nice-way-to-think-of-it-is-to-think-that-you-start-with-the-problem-at-hand,-but-design-features-constrained-by-the-data-you-have-available.-If-you-have-many-independent-features-that-each-correlate-well-with-the-class,-learning-is-easy.-On-the-other-hand,-if-the-class-is-a-very-complex-function-of-the-features,-you-may-not-be-able-to-learn-it.">A nice way to think of it is to think that you start with the problem at hand, but design features constrained by the data you have available. If you have many independent features that each correlate well with the class, learning is easy. On the other hand, if the class is a very complex function of the features, you may not be able to learn it.<a class="anchor-link" href="#A-nice-way-to-think-of-it-is-to-think-that-you-start-with-the-problem-at-hand,-but-design-features-constrained-by-the-data-you-have-available.-If-you-have-many-independent-features-that-each-correlate-well-with-the-class,-learning-is-easy.-On-the-other-hand,-if-the-class-is-a-very-complex-function-of-the-features,-you-may-not-be-able-to-learn-it.">&#182;</a></h4><p>In the context of this problem, we would like to predict the genre of a movie. what we have access to - movie overviews, which are text descriptions of the movie plot. The hypothesis makes sense, overview is a short description of the story and the story is clearly important in assigning genres to movies.</p>
<p>So, let's improve our features by playing with the words in the overviews in our data. One interesting way to go back to what we discussed earlier - TF-IDF. We originally used it to filter words, but we can also assign the tf-idf values as "importance" values to words, as opposed to treating them all equally. Tf-idf simply tries to identify the assign a weightage to each word in the bag of words.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Once again, the way it works is - Most movie descriptions have the word "The" in it. Obviously, it doesn't tell you anything special about it. So weightage should be inversely proportional to how many movies have the word in their description. This is the IDF part.</p>
<p>On the other hand, for the movie interstellar, if the description has the word Space 5 times, and wormhole 2 times, then it's probably more about Space than about wormhole. Thus, space should have a high weightage. This is the TF part.</p>
<p>We simply use TF-IDf to assign weightage to every word in the bag of words. Which makes sense, right? :)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[79]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.feature_extraction.text</span> <span class="kn">import</span> <span class="n">TfidfTransformer</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[80]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">tfidf_transformer</span> <span class="o">=</span> <span class="n">TfidfTransformer</span><span class="p">()</span>
<span class="n">X_tfidf</span> <span class="o">=</span> <span class="n">tfidf_transformer</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
<span class="n">X_tfidf</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[80]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1595, 1365)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's divide our X and Y matrices into train and test split. We train the model on the train split, and report the performance on the test split. Think of this like the questions you do in the problem sets v/s the exam. Of course, they are both (assumed to be) from the same population of questions. And doing well on Problem Sets is a good indicator that you'll do well in exams, but really, you must test before you can make any claims about you knowing the subject.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[81]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">msk</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="n">X_tfidf</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">&lt;</span> <span class="mf">0.8</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[82]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X_train_tfidf</span><span class="o">=</span><span class="n">X_tfidf</span><span class="p">[</span><span class="n">msk</span><span class="p">]</span>
<span class="n">X_test_tfidf</span><span class="o">=</span><span class="n">X_tfidf</span><span class="p">[</span><span class="o">~</span><span class="n">msk</span><span class="p">]</span>
<span class="n">Y_train</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="n">msk</span><span class="p">]</span>
<span class="n">Y_test</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="o">~</span><span class="n">msk</span><span class="p">]</span>
<span class="n">positions</span><span class="o">=</span><span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">movies_with_overviews</span><span class="p">))</span>
<span class="c1"># print positions</span>
<span class="n">test_movies</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">positions</span><span class="p">)[</span><span class="o">~</span><span class="n">msk</span><span class="p">]</span>
<span class="c1"># test_movies</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[83]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.multiclass</span> <span class="kn">import</span> <span class="n">OneVsRestClassifier</span>
<span class="kn">from</span> <span class="nn">sklearn.svm</span> <span class="kn">import</span> <span class="n">SVC</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">GridSearchCV</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">f1_score</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">make_scorer</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">classification_report</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[98]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">parameters</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;kernel&#39;</span><span class="p">:[</span><span class="s1">&#39;linear&#39;</span><span class="p">],</span> <span class="s1">&#39;C&#39;</span><span class="p">:[</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">]}</span>
<span class="n">gridCV</span> <span class="o">=</span> <span class="n">GridSearchCV</span><span class="p">(</span><span class="n">SVC</span><span class="p">(</span><span class="n">class_weight</span><span class="o">=</span><span class="s1">&#39;balanced&#39;</span><span class="p">),</span> <span class="n">parameters</span><span class="p">,</span> <span class="n">scoring</span><span class="o">=</span><span class="n">make_scorer</span><span class="p">(</span><span class="n">f1_score</span><span class="p">,</span> <span class="n">average</span><span class="o">=</span><span class="s1">&#39;micro&#39;</span><span class="p">))</span>
<span class="n">classif</span> <span class="o">=</span> <span class="n">OneVsRestClassifier</span><span class="p">(</span><span class="n">gridCV</span><span class="p">)</span>

<span class="n">classif</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train_tfidf</span><span class="p">,</span> <span class="n">Y_train</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[98]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>OneVsRestClassifier(estimator=GridSearchCV(cv=None, error_score=&#39;raise&#39;,
       estimator=SVC(C=1.0, cache_size=200, class_weight=&#39;balanced&#39;, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=&#39;auto&#39;, kernel=&#39;rbf&#39;,
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False),...refit=True, return_train_score=True,
       scoring=make_scorer(f1_score, average=micro), verbose=0),
          n_jobs=1)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[99]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">predstfidf</span><span class="o">=</span><span class="n">classif</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test_tfidf</span><span class="p">)</span>

<span class="k">print</span> <span class="n">classification_report</span><span class="p">(</span><span class="n">Y_test</span><span class="p">,</span> <span class="n">predstfidf</span><span class="p">,</span> <span class="n">target_names</span><span class="o">=</span><span class="n">genre_names</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>                 precision    recall  f1-score   support

      Adventure       0.42      0.57      0.48        56
        Fantasy       0.46      0.67      0.55        45
      Animation       0.27      0.42      0.33        31
          Drama       0.60      0.57      0.58       132
         Horror       0.00      0.00      0.00        41
         Action       0.49      0.67      0.57        70
         Comedy       0.40      0.53      0.46        77
        History       0.40      0.37      0.38        27
        Western       0.33      0.14      0.20         7
       Thriller       0.26      1.00      0.41        76
          Crime       0.46      0.48      0.47        46
    Documentary       0.61      0.67      0.64        21
Science Fiction       0.12      1.00      0.22        36
        Mystery       0.23      0.37      0.29        35
          Music       0.95      0.59      0.73        34
        Romance       0.35      0.50      0.41        46
         Family       0.32      0.38      0.35        42
            War       0.27      0.44      0.33         9
        Foreign       0.00      0.00      0.00         4
       TV Movie       0.00      0.00      0.00         5

    avg / total       0.40      0.56      0.44       840

</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As you can see, the performance is by and large poorer for movies which are less represented like War and animation, and better for categories like Drama.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Numbers aside, let's look at our model's predictions for a small sample of movies from our test set.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[101]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">genre_list</span><span class="o">=</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[102]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">predictions</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">X_test_tfidf</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
    <span class="n">pred_genres</span><span class="o">=</span><span class="p">[]</span>
    <span class="n">movie_label_scores</span><span class="o">=</span><span class="n">predstfidf</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="c1">#     print movie_label_scores</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
        <span class="c1">#print j</span>
        <span class="k">if</span> <span class="n">movie_label_scores</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">!=</span><span class="mi">0</span><span class="p">:</span>
            <span class="n">genre</span><span class="o">=</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">j</span><span class="p">]]</span>
            <span class="n">pred_genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">genre</span><span class="p">)</span>
    <span class="n">predictions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pred_genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[103]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;classifer_svc&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">classif</span><span class="p">,</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[115]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">X_test_tfidf</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">50</span>==0 and i!=0:
        <span class="k">print</span> <span class="s1">&#39;MOVIE: &#39;</span><span class="p">,</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;title&#39;</span><span class="p">],</span><span class="s1">&#39;</span><span class="se">\t</span><span class="s1">PREDICTION: &#39;</span><span class="p">,</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">predictions</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>MOVIE:  The Walk 	PREDICTION:  Adventure,Fantasy,Animation,Action,Thriller,Science Fiction
MOVIE:  Cinderella 	PREDICTION:  Adventure,Fantasy,Action,Thriller,Science Fiction
MOVIE:  Liza, the Fox-Fairy 	PREDICTION:  Drama,Thriller,Science Fiction,Romance,War
MOVIE:  The Polar Express 	PREDICTION:  Adventure,Action,Thriller,Science Fiction,Family
MOVIE:  Patema Inverted 	PREDICTION:  Thriller,Science Fiction,Music
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's try our second model? The naive bayes model.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[116]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.naive_bayes</span> <span class="kn">import</span> <span class="n">MultinomialNB</span>
<span class="n">classifnb</span> <span class="o">=</span> <span class="n">OneVsRestClassifier</span><span class="p">(</span><span class="n">MultinomialNB</span><span class="p">())</span>
<span class="n">classifnb</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">msk</span><span class="p">]</span><span class="o">.</span><span class="n">toarray</span><span class="p">(),</span> <span class="n">Y_train</span><span class="p">)</span>
<span class="n">predsnb</span><span class="o">=</span><span class="n">classifnb</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="o">~</span><span class="n">msk</span><span class="p">]</span><span class="o">.</span><span class="n">toarray</span><span class="p">())</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[117]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="n">f2</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;classifer_nb&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">classifnb</span><span class="p">,</span><span class="n">f2</span><span class="p">)</span>
<span class="n">f2</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[118]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">predictionsnb</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">X_test_tfidf</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
    <span class="n">pred_genres</span><span class="o">=</span><span class="p">[]</span>
    <span class="n">movie_label_scores</span><span class="o">=</span><span class="n">predsnb</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
        <span class="c1">#print j</span>
        <span class="k">if</span> <span class="n">movie_label_scores</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">!=</span><span class="mi">0</span><span class="p">:</span>
            <span class="n">genre</span><span class="o">=</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">j</span><span class="p">]]</span>
            <span class="n">pred_genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">genre</span><span class="p">)</span>
    <span class="n">predictionsnb</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pred_genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[120]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">X_test_tfidf</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">50</span>==0 and i!=0:
        <span class="k">print</span> <span class="s1">&#39;MOVIE: &#39;</span><span class="p">,</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">&#39;title&#39;</span><span class="p">],</span><span class="s1">&#39;</span><span class="se">\t</span><span class="s1">PREDICTION: &#39;</span><span class="p">,</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">predictionsnb</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>MOVIE:  The Walk 	PREDICTION:  Adventure,Fantasy,Animation,Science Fiction
MOVIE:  Cinderella 	PREDICTION:  Adventure,Action,Science Fiction
MOVIE:  Liza, the Fox-Fairy 	PREDICTION:  Drama,Romance
MOVIE:  The Polar Express 	PREDICTION:  Science Fiction
MOVIE:  Patema Inverted 	PREDICTION:  Documentary,Music
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As can be seen above, the results seem promising, but how do we really compare the two models? We need to quantify our performance so that we can say which one's better. Takes us back to what we discussed right in the beginning - we're learning a function $g$ which can approximate the original unknown function $f$. For some values of $x_i$, the predictions will be wrong for sure, and we want to minimize it.</p>
<p>For multi label systems, we often keep track of performance using "Precision" and "Recall". These are standard metrics, and you can google to read up more about them if you're new to these terms.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Evaluation-Metrics">Evaluation Metrics<a class="anchor-link" href="#Evaluation-Metrics">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>We will use the standard precision recall metrics for evaluating our system.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[46]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">precision_recall</span><span class="p">(</span><span class="n">gt</span><span class="p">,</span><span class="n">preds</span><span class="p">):</span>
    <span class="n">TP</span><span class="o">=</span><span class="mi">0</span>
    <span class="n">FP</span><span class="o">=</span><span class="mi">0</span>
    <span class="n">FN</span><span class="o">=</span><span class="mi">0</span>
    <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">gt</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">preds</span><span class="p">:</span>
            <span class="n">TP</span><span class="o">+=</span><span class="mi">1</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">FN</span><span class="o">+=</span><span class="mi">1</span>
    <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">preds</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">p</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">gt</span><span class="p">:</span>
            <span class="n">FP</span><span class="o">+=</span><span class="mi">1</span>
    <span class="k">if</span> <span class="n">TP</span><span class="o">+</span><span class="n">FP</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">precision</span><span class="o">=</span><span class="mi">0</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">precision</span><span class="o">=</span><span class="n">TP</span><span class="o">/</span><span class="nb">float</span><span class="p">(</span><span class="n">TP</span><span class="o">+</span><span class="n">FP</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">TP</span><span class="o">+</span><span class="n">FN</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">recall</span><span class="o">=</span><span class="mi">0</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">recall</span><span class="o">=</span><span class="n">TP</span><span class="o">/</span><span class="nb">float</span><span class="p">(</span><span class="n">TP</span><span class="o">+</span><span class="n">FN</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">precision</span><span class="p">,</span><span class="n">recall</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[122]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">precs</span><span class="o">=</span><span class="p">[]</span>
<span class="n">recs</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">test_movies</span><span class="p">)):</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">1</span>==0:
        <span class="n">pos</span><span class="o">=</span><span class="n">test_movies</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
        <span class="n">test_movie</span><span class="o">=</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span>
        <span class="n">gtids</span><span class="o">=</span><span class="n">test_movie</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
        <span class="n">gt</span><span class="o">=</span><span class="p">[]</span>
        <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">gtids</span><span class="p">:</span>
            <span class="n">g_name</span><span class="o">=</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">g</span><span class="p">]</span>
            <span class="n">gt</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">g_name</span><span class="p">)</span>
<span class="c1">#         print predictions[i],movies_with_overviews[i][&#39;title&#39;],gt</span>
        <span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">=</span><span class="n">precision_recall</span><span class="p">(</span><span class="n">gt</span><span class="p">,</span><span class="n">predictions</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
        <span class="n">precs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
        <span class="n">recs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>

<span class="k">print</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">precs</span><span class="p">)),</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">recs</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>0.33085149314 0.570960451977
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[123]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">precs</span><span class="o">=</span><span class="p">[]</span>
<span class="n">recs</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">test_movies</span><span class="p">)):</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">1</span>==0:
        <span class="n">pos</span><span class="o">=</span><span class="n">test_movies</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
        <span class="n">test_movie</span><span class="o">=</span><span class="n">movies_with_overviews</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span>
        <span class="n">gtids</span><span class="o">=</span><span class="n">test_movie</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
        <span class="n">gt</span><span class="o">=</span><span class="p">[]</span>
        <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">gtids</span><span class="p">:</span>
            <span class="n">g_name</span><span class="o">=</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">g</span><span class="p">]</span>
            <span class="n">gt</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">g_name</span><span class="p">)</span>
<span class="c1">#         print predictions[i],movies_with_overviews[i][&#39;title&#39;],gt</span>
        <span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">=</span><span class="n">precision_recall</span><span class="p">(</span><span class="n">gt</span><span class="p">,</span><span class="n">predictionsnb</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
        <span class="n">precs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
        <span class="n">recs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>

<span class="k">print</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">precs</span><span class="p">)),</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">recs</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>0.48893866021 0.549604519774
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The average precision and recall scores for our samples are pretty good! Models seem to be working! Also, we can see that the Naive Bayes performs outperforms SVM. <strong>I strongly suggest you to go read about Multinomial Bayes and think about why it works so well for "Document Classification", which is very similar to our case as every movie overview can be thought of as a document we are assigning labels to.</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-6---Deep-Learning-:-an-intuitive-overview">Section 6 - Deep Learning : an intuitive overview<a class="anchor-link" href="#Section-6---Deep-Learning-:-an-intuitive-overview">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The above results were good, but it's time to bring out the big guns. So first and foremost, let's get a very short idea about what's deep learning. This is for peope who don't have background in this - it's high level and gives just the intuition.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>As described above, the two most immportant concepts in doing good classification (or regression) are to 1) use the right representation which captures the right information about the data which is relavant to the problem at hand 2) Using the right model which has the capability of making sense of the representation fed to it.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>While for the second part we have complicated and powerful models that we have studied at length, we don't seem to have a principled, mathematical way of doing the first part - i.e. representation. What we did above was to see "What makes sense", and go from there. That is not a good approach for complex data/ complex problems. Is there some way to automate this? Deep Learning, does just this.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>To just emphasize the importance of representation in the complex tasks we usually attempt with Deep Learning, let me talk about the original problem which made it famous. The paper is often reffered to as the "Imagenet Challenge Paper", and it was basically working on object recognition in images. Let's try to think about an algorithm that tries to detect a chair.</p>
<h2 id="If-I-ask-you-to-&quot;Define&quot;-a-chair,-how-would-you?---Something-with-4-legs?">If I ask you to "Define" a chair, how would you? - Something with 4 legs?<a class="anchor-link" href="#If-I-ask-you-to-&quot;Define&quot;-a-chair,-how-would-you?---Something-with-4-legs?">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><img src="chair1.png" height="400" width="400"></p>
<h3><center>All are chairs, none with 4 legs. (Pic Credit: Zoya Bylinskii)</center></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="How-about-some-surface-that-we-sit-on-then?">How about some surface that we sit on then?<a class="anchor-link" href="#How-about-some-surface-that-we-sit-on-then?">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><img src="chair2.png" height="400" width="400"></p>
<h3><center>All are surfaces we sit on, none are chairs. (Pic Credit: Zoya Bylinskii)</center></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Clearly, these definitions won't work and we need something more complicated. Sadly, we can't come up with a simple text rule that our computer can search for! And we take a more principled approach.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The "Deep" in the deep learning comes from the fact that it was conventionally applied to Neural Networks. Neural Networks, as we all know, are structures organized in layers. Layers of computations. Why do we need layers? Because these layers can be seen as sub-tasks that we do in the complicated task of identifying a chair. It can be thought as a heirarchical break down of a complicated job into smalled sub-tasks.</p>
<p>Mathematically, each layer acts like a space transformation which takes the pixel values to a high dimensional space. When we start out, every pixel in the image is given equal importance in our matrix. With each layer, convolution operations give some parts more importance, and some lesser importance. In doing so, we transform our images to a space in which similar looking objects/object parts are closer (We are basically learning this space transformation in deep learning, nothing else)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>What exactly was learnt by these neural networks is hard to know, and an active area of research. But one very crude way to visualize what it does is to think like - It starts by learning very generic features in the first layer. Something as simple as vertical and horizontal lines. In the next layer, it learns that if you combine the vectors representing vertical and horizontal vectors in different ratios, you can make all possible slanted lines. Next layer learns to combine lines to form curves - Say, something like the outline of a face. These curves come together to form 3D objects. And so on. Building sub-modules, combining them in the right way which can give it semantics.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><strong>So, in a nutshell, the first few layers of a "Deep" network learn the right representation of the data, given the problem (which is mathematically described by your objective function trying to minimize difference between ground truth and predicted labels). The last layer simply looks how close or far apart things are in this high dimensional space.</strong></p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Hence, we can give any kind of data a high dimensional representation using neural networks. Below we will see high dimensional representations of both words in overviews (text) and posters (image). Let's get started with the posters i.e. extracting visual features from posters using deep learning.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-7---Deep-Learning-for-predicting-genre-from-poster">Section 7 - Deep Learning for predicting genre from poster<a class="anchor-link" href="#Section-7---Deep-Learning-for-predicting-genre-from-poster">&#182;</a></h1><p>Once again, we must make an implementation decision. This time, it has more to do with how much time are we willing to spend in return for added accuracy. We are going to use here a technique that is commonly referred to as Pre-Training in Machine Learning Literature.</p>
<p>Instead of me trying to re-invent the wheel here, I am going to borrow this short section on pre-training from Stanford University's lecture on <a href='http://cs231n.github.io/transfer-learning/'> CNN's</a>. To quote -</p>
<p>''In practice, very few people train an entire Convolutional Network from scratch (with random initialization), because it is relatively rare to have a dataset of sufficient size. Instead, it is common to pretrain a ConvNet on a very large dataset (e.g. ImageNet, which contains 1.2 million images with 1000 categories), and then use the ConvNet either as an initialization or a fixed feature extractor for the task of interest. ''</p>
<p>There are three broad ways in which transfer learning or pre-training can be done. (The 2 concepts are different and to understand the difference clearly, I suggest you read the linked lecture thoroughly). The way we are going to about it is by using a pre-trained, released ConvNet as feature extractor. Take a ConvNet pretrained on ImageNet (a popular object detection dataset), remove the last fully-connected layer. After removing the last layer, what we have is just another neural network i.e. a stack of space tranformations. But, originally the output of this stack can be pumped into a single layer which can classify the image into categories like Car, Dog, Cat and so on.</p>
<p>What this means, is that in the space this stack transforms the images to, all images which contain a "dog" are closer to each other, and all images containing a "cat" are closer. Thus, it is a meaningful space where images with similar objects are closer.</p>
<p>Think about it, now if we pump our posters through this stack, it will embed them in a space where posters which contain similar objects are closer. This is a very meaningful feature engineering method! While this may not be ideal for genre prediction, it might be quite meaningful. For example, all posters with a gun or a car are probably action. While a smiling couple would point to romance or drama. The alternative would be to train the CNN from scratch which is fairly computationally intensive and involves a lot of tricks to get the CNN training to converge to the optimal space tranformation.</p>
<p>This way, we can start off with something strong, and then build on top. We pump our images through the pre-trained network to extract the visual features from the posters. Then, using these features as descriptors for the image, and genres as the labels, we train a simpler neural network from scratch which learns to do simply classification on this dataset. These 2 steps are exactly what we are going to do for predicting genres from movie posters.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Deep-Learning-to-extract-visual-features-from-posters">Deep Learning to extract visual features from posters<a class="anchor-link" href="#Deep-Learning-to-extract-visual-features-from-posters">&#182;</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The basic problem here we are answering is that can we use the posters to predict genre. First check - Does this hypothesis make sense? Yes. Because that's what graphic designers do for a living. They leave visual cues to semantics. They make sure that when we look at the poster of a horror movie, we know it's not a happy image. Things like that. Can our deep learning system infer such subtleties? Let's find out!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For Visual features, either we can train a deep neural network ourselves from scratch, or we can use a pre-trained one made available to us from the Visual Geometry Group at Oxford University, one of the most popular methods. This is called the VGG-net. Or as they call it, we will extract the VGG features of an image. Mathematically, as mentioned, it's just a space transformation in the form of layers. So, we simply need to perform this chain of transformations on our image, right? Keras is a library that makes it very easy for us to do this. Some other common ones are Tensorflow and PyTorch. While the latter two are very powerful and customizable and used more often in practice, Keras makes it easy to prototype by keeping the syntax simple.</p>
<p>We will be working with Keras to keep things simple in code, so that we can spend more time understanding and less time coding. Some common ways people refer to this step are - "Getting the VGG features of an image", or "Forward Propogating the image through VGG and chopping off the last layer". In keras, this is as easy as writing 4 lines.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[3]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Loading the list of movies we had downloaded posters for eariler - </span>
<span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;poster_movies.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;r&#39;</span><span class="p">)</span>
<span class="n">poster_movies</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[4]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">keras.applications.vgg16</span> <span class="kn">import</span> <span class="n">VGG16</span>
<span class="kn">from</span> <span class="nn">keras.preprocessing</span> <span class="kn">import</span> <span class="n">image</span>
<span class="kn">from</span> <span class="nn">keras.applications.vgg16</span> <span class="kn">import</span> <span class="n">preprocess_input</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pickle</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">VGG16</span><span class="p">(</span><span class="n">weights</span><span class="o">=</span><span class="s1">&#39;imagenet&#39;</span><span class="p">,</span> <span class="n">include_top</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stderr output_text">
<pre>Using TensorFlow backend.
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[467]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">allnames</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">poster_folder</span><span class="p">)</span>
<span class="n">imnames</span><span class="o">=</span><span class="p">[</span><span class="n">j</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">allnames</span> <span class="k">if</span> <span class="n">j</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">&#39;.jpg&#39;</span><span class="p">)]</span>
<span class="n">feature_list</span><span class="o">=</span><span class="p">[]</span>
<span class="n">genre_list</span><span class="o">=</span><span class="p">[]</span>
<span class="n">file_order</span><span class="o">=</span><span class="p">[]</span>
<span class="k">print</span> <span class="s2">&quot;Starting extracting VGG features for scraped images. This will take time, Please be patient...&quot;</span>
<span class="k">print</span> <span class="s2">&quot;Total images = &quot;</span><span class="p">,</span><span class="nb">len</span><span class="p">(</span><span class="n">imnames</span><span class="p">)</span>
<span class="n">failed_files</span><span class="o">=</span><span class="p">[]</span>
<span class="n">succesful_files</span><span class="o">=</span><span class="p">[]</span>
<span class="n">i</span><span class="o">=</span><span class="mi">0</span>
<span class="k">for</span> <span class="n">mov</span> <span class="ow">in</span> <span class="n">poster_movies</span><span class="p">:</span>
    <span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
    <span class="n">mov_name</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;original_title&#39;</span><span class="p">]</span>
    <span class="n">mov_name1</span><span class="o">=</span><span class="n">mov_name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
    <span class="n">poster_name</span><span class="o">=</span><span class="n">mov_name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span><span class="s1">&#39;_&#39;</span><span class="p">)</span><span class="o">+</span><span class="s1">&#39;.jpg&#39;</span>
    <span class="k">if</span> <span class="n">poster_name</span> <span class="ow">in</span> <span class="n">imnames</span><span class="p">:</span>
        <span class="n">img_path</span><span class="o">=</span><span class="n">poster_folder</span><span class="o">+</span><span class="n">poster_name</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">img</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">load_img</span><span class="p">(</span><span class="n">img_path</span><span class="p">,</span> <span class="n">target_size</span><span class="o">=</span><span class="p">(</span><span class="mi">224</span><span class="p">,</span> <span class="mi">224</span><span class="p">))</span>
            <span class="n">succesful_files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">imname</span><span class="p">)</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">img_to_array</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">expand_dims</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">preprocess_input</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
            <span class="n">features</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
            <span class="n">file_order</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">img_path</span><span class="p">)</span>
            <span class="n">feature_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">features</span><span class="p">)</span>
            <span class="n">genre_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">])</span>
            <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">feature_list</span><span class="p">))</span><span class="o">==</span><span class="mf">0.0</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="s1">&#39;problematic&#39;</span><span class="p">,</span><span class="n">i</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">250</span>==0 or i==1:
                <span class="k">print</span> <span class="s2">&quot;Working on Image : &quot;</span><span class="p">,</span><span class="n">i</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="n">failed_files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">imname</span><span class="p">)</span>
            <span class="k">continue</span>
        
    <span class="k">else</span><span class="p">:</span>
        <span class="k">continue</span>
<span class="k">print</span> <span class="s2">&quot;Done with all features, please pickle for future use!&quot;</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Starting extracting VGG features for scraped images. This will take time, Please be patient...
Total images =  1347
Working on Image :  250
Working on Image :  500
Working on Image :  750
Working on Image :  1000
Working on Image :  1250
Working on Image :  1500
Done with all features, please pickle for future use!
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[476]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">genre_list</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[476]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>1317</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[477]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">feature_list</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[477]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>1317</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[472]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Reading from pickle below, this code is not to be run.</span>
<span class="n">list_pickled</span><span class="o">=</span><span class="p">(</span><span class="n">feature_list</span><span class="p">,</span><span class="n">file_order</span><span class="p">,</span><span class="n">failed_files</span><span class="p">,</span><span class="n">succesful_files</span><span class="p">,</span><span class="n">genre_list</span><span class="p">)</span>
<span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;posters_new_features.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">list_pickled</span><span class="p">,</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s2">&quot;Features dumped to pickle file&quot;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Features dumped to pickle file
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[5]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f7</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;posters_new_features.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">list_pickled</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f7</span><span class="p">)</span>
<span class="n">f7</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1"># (feature_list2,file_order2)=list_pickled</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Training-a-simple-neural-network-model-using-these-VGG-features.">Training a simple neural network model using these VGG features.<a class="anchor-link" href="#Training-a-simple-neural-network-model-using-these-VGG-features.">&#182;</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[6]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="p">(</span><span class="n">feature_list</span><span class="p">,</span><span class="n">files</span><span class="p">,</span><span class="n">failed</span><span class="p">,</span><span class="n">succesful</span><span class="p">,</span><span class="n">genre_list</span><span class="p">)</span><span class="o">=</span><span class="n">list_pickled</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's first get the labels on our 1342 samples first! As image download fails on a few instances, the best way to work with the right model is to read the poster names downloaded, and working from there. These posters cannot be uploaded to Github as they are too large, and so are being downloaded and read from my local computer. If you do re-do it, you might have to check and edit the paths in the code to make sure it runs.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[7]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">,</span><span class="n">c</span><span class="p">,</span><span class="n">d</span><span class="p">)</span><span class="o">=</span><span class="n">feature_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span>
<span class="n">feature_size</span><span class="o">=</span><span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">*</span><span class="n">c</span><span class="o">*</span><span class="n">d</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>This looks odd, why are we re-running the loop we ran above again below? The reason is simple, the most important thing to know about numpy is that using vstack() and hstack() are highly sub-optimal. Numpy arrays when created, a fixed size is allocated in the memory and when we stack, a new one is copied and created in a new location. This makes the code really, really slow. The best way to do it (and this remains the same with MATLAB matrices if you work with them), is to create a numpy array of zeros, and over-write it row by row. The above code was just to see what size numpy array we will need!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The final movie poster set for which we have all the information we need, is 1265 movies. In the above code we are making an X numpy array containing the visual features of one image per row. So, the VGG features are reshaped to be in the shape (1,25088) and we finally obtain a matrix of shape (1265,25088)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[8]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">np_features</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">feature_list</span><span class="p">),</span><span class="n">feature_size</span><span class="p">))</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">feature_list</span><span class="p">)):</span>
    <span class="n">feat</span><span class="o">=</span><span class="n">feature_list</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">reshaped_feat</span><span class="o">=</span><span class="n">feat</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">np_features</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">reshaped_feat</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[9]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># np_features[-1]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[10]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">=</span><span class="n">np_features</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[11]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">MultiLabelBinarizer</span>
<span class="n">mlb</span><span class="o">=</span><span class="n">MultiLabelBinarizer</span><span class="p">()</span>
<span class="n">Y</span><span class="o">=</span><span class="n">mlb</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">genre_list</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[12]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[12]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1317, 20)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Our binarized Y numpy array contains the binarized labels corresponding to the genre IDs of the 1277 movies</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[503]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">visual_problem_data</span><span class="o">=</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">Y</span><span class="p">)</span>
<span class="n">f8</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;visual_problem_data_clean.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">visual_problem_data</span><span class="p">,</span><span class="n">f8</span><span class="p">)</span>
<span class="n">f8</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[504]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f8</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;visual_problem_data_clean.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">visual_features</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f8</span><span class="p">)</span>
<span class="n">f8</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[505]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">Y</span><span class="p">)</span><span class="o">=</span><span class="n">visual_features</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[506]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[506]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1317, 25088)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[507]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">mask</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">X</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mf">0.8</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[508]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X_train</span><span class="o">=</span><span class="n">X</span><span class="p">[</span><span class="n">mask</span><span class="p">]</span>
<span class="n">X_test</span><span class="o">=</span><span class="n">X</span><span class="p">[</span><span class="o">~</span><span class="n">mask</span><span class="p">]</span>
<span class="n">Y_train</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="n">mask</span><span class="p">]</span>
<span class="n">Y_test</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="o">~</span><span class="n">mask</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[510]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X_test</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[510]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(264, 25088)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now, we create our own keras neural network to use the VGG features and then classify movie genres. Keras makes this super easy.</p>
<p>Neural network architectures have gotten complex over the years. But the simplest ones contain very standard computations organized in layers, as described above. Given the popularity of some of these, Keras makes it as easy as writing out the names of these operations in a sequential order. This way you can make a network while completely avoiding the Mathematics (HIGHLY RECOMMENDED SPENDING MORE TIME ON THE MATH THOUGH)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Sequential() allows us to make models the follow this sequential order of layers. Different kinds of layers like Dense, Conv2D etc can be used, and many activation functions like RELU, Linear etc are also available.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Important-Question-:-Why-do-we-need-activation-functions?">Important Question : Why do we need activation functions?<a class="anchor-link" href="#Important-Question-:-Why-do-we-need-activation-functions?">&#182;</a></h1><h4 id="Copy-pasting-the-answer-I-wrote-for-this-question-on-Quora-Feel-free-to-leave-comments-there.">Copy pasting the answer I wrote for this question on <a href="https://www.quora.com/Why-do-neural-networks-need-an-activation-function/answer/Spandan-Madan?srid=5ydm">Quora</a> Feel free to leave comments there.<a class="anchor-link" href="#Copy-pasting-the-answer-I-wrote-for-this-question-on-Quora-Feel-free-to-leave-comments-there.">&#182;</a></h4><p>""Sometimes, we tend to get lost in the jargon and confuse things easily, so the best way to go about this is getting back to our basics.</p>
<p>Don’t forget what the original premise of machine learning (and thus deep learning) is - IF the input and output are related by a function y=f(x), then if we have x, there is no way to exactly know f unless we know the process itself. However, machine learning gives you the ability to approximate f with a function g, and the process of trying out multiple candidates to identify the function g best approximating f is called machine learning.</p>
<p>Ok, that was machine learning, and how is deep learning different? Deep learning simply tries to expand the possible kind of functions that can be approximated using the above mentioned machine learning paradigm. Roughly speaking, if the previous model could learn say 10,000 kinds of functions, now it will be able to learn say 100,000 kinds (in actuality both are infinite spaces but one is larger than the other, because maths is cool that ways.)</p>
<p>If you want to know the mathematics of it, go read about VC dimension and how more layers in a network affect it. But I will avoid the mathematics here and rely on your intuition to believe me when I say that not all data can be classified correctly into categories using a linear function. So, we need our deep learning model to be able to approximate more complex functions than just a linear function.</p>
<p>Now, let’s come to your non linearity bit. Imagine a linear function y=2x+3, and another one y=4x+7. What happens if I pool them and take an average? I get another linear function y= 3x+5. So instead of doing those two computations separately and then averaging it out, I could have just used the single linear function y=3x+5. Obviously, this logic holds good if I have more than 2 such linear functions. This is exactly what will happen if you don’t have have non-linearities in your nodes, and also what others have written in their answers.</p>
<p>It simply follows from the definition of a linear function -</p>
<p>(i) If you take two linear functions, AND</p>
<p>(ii)Take a linear combination of them (which is how we combine the outputs of multiple nodes of a network)</p>
<p>You are BOUND to get a linear function because f(x)+g(x)=mx+b+nx+c=(m+n)x+(b+c)= say h(x).</p>
<p>And you could in essence replace your whole network by a simple matrix transformation which accounts for all linear combinations and up/downsamplings.</p>
<p>In a nutshell, you’ll only be trying to learn a linear approximation for original function f relating the input and the output. Which as we discussed above, is not always the best approximation. Adding non-linearities ensures that you can learn more complex functions by approximating every non-linear function as a LINEAR combination of a large number of non-linear functions.</p>
<p>Still new to the field, so if there’s something wrong here please comment below! Hope it helps""</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h4 id="Let's-train-our-model-then,-using-the-features-we-extracted-from-VGG-net">Let's train our model then, using the features we extracted from VGG net<a class="anchor-link" href="#Let's-train-our-model-then,-using-the-features-we-extracted-from-VGG-net">&#182;</a></h4><p>The model we will use has just 1 hidden layer between the VGG features and the final output layer. The simplest neural network you can get. An image goes into this network with the dimensions (1,25088), the first layer's output is 1024 dimensional. This hidden layer output undergoes a pointwise RELU activation. This output gets transformed into the output layer of 20 dimensions. It goes through a sigmoid.</p>
<p>The sigmoid, or the squashing function as it is often called, is a function which squashes numbers between 0 and 1. What are you reminded of when you think of numebers between 0 and 1? Right, probability.</p>
<p>By squashing the score of each of the 20 output labels between 0 and 1, sigmoid lets us interpret their scores as probabilities. Then, we can just pick the classes with the top 3 or 5 probability scores as the predicted genres for the movie poster! Simple!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[412]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Y_train[115]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[549]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">keras.models</span> <span class="kn">import</span> <span class="n">Sequential</span>
<span class="kn">from</span> <span class="nn">keras.layers</span> <span class="kn">import</span> <span class="n">Dense</span><span class="p">,</span> <span class="n">Activation</span>
<span class="kn">from</span> <span class="nn">keras</span> <span class="kn">import</span> <span class="n">optimizers</span>
<span class="n">model_visual</span> <span class="o">=</span> <span class="n">Sequential</span><span class="p">([</span>
    <span class="n">Dense</span><span class="p">(</span><span class="mi">1024</span><span class="p">,</span> <span class="n">input_shape</span><span class="o">=</span><span class="p">(</span><span class="mi">25088</span><span class="p">,)),</span>
    <span class="n">Activation</span><span class="p">(</span><span class="s1">&#39;relu&#39;</span><span class="p">),</span>
    <span class="n">Dense</span><span class="p">(</span><span class="mi">256</span><span class="p">),</span>
    <span class="n">Activation</span><span class="p">(</span><span class="s1">&#39;relu&#39;</span><span class="p">),</span>
    <span class="n">Dense</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span>
    <span class="n">Activation</span><span class="p">(</span><span class="s1">&#39;sigmoid&#39;</span><span class="p">),</span>
<span class="p">])</span>
<span class="n">opt</span> <span class="o">=</span> <span class="n">optimizers</span><span class="o">.</span><span class="n">rmsprop</span><span class="p">(</span><span class="n">lr</span><span class="o">=</span><span class="mf">0.0001</span><span class="p">,</span> <span class="n">decay</span><span class="o">=</span><span class="mf">1e-6</span><span class="p">)</span>

<span class="c1">#sgd = optimizers.SGD(lr=0.05, decay=1e-6, momentum=0.4, nesterov=False)</span>
<span class="n">model_visual</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">optimizer</span><span class="o">=</span><span class="n">opt</span><span class="p">,</span>
              <span class="n">loss</span><span class="o">=</span><span class="s1">&#39;binary_crossentropy&#39;</span><span class="p">,</span>
              <span class="n">metrics</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;accuracy&#39;</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>We train the model using the fit() function. The parameters it takes are - training features and training labels, epochs, batch_size and verbose.</p>
<p>Simplest one - verbose. 0="dont print anything as you work", 1="Inform me as you go".</p>
<p>Often the data set is too large to be loaded into the RAM. So, we load data in batches. For batch_size=32 and epochs=10, the model starts loading rows from X in batches of 32 everytime it calculates the loss and updates the model. It keeps on going till it has covered all the samples 10 times.</p>
<p>So, the no. of times model is updated = (Total Samples/Batch Size) * (Epochs)</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[550]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">model_visual</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">Y_train</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">64</span><span class="p">,</span><span class="n">verbose</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Epoch 1/10
1053/1053 [==============================] - 7s - loss: 2.3120 - acc: 0.8160     
Epoch 2/10
1053/1053 [==============================] - 6s - loss: 1.6045 - acc: 0.8724     
Epoch 3/10
1053/1053 [==============================] - 7s - loss: 1.1555 - acc: 0.9078     
Epoch 4/10
1053/1053 [==============================] - 7s - loss: 0.9149 - acc: 0.9264     
Epoch 5/10
1053/1053 [==============================] - 6s - loss: 0.7455 - acc: 0.9420     
Epoch 6/10
1053/1053 [==============================] - 6s - loss: 0.6218 - acc: 0.9522     
Epoch 7/10
1053/1053 [==============================] - 7s - loss: 0.5393 - acc: 0.9623     
Epoch 8/10
1053/1053 [==============================] - 7s - loss: 0.5104 - acc: 0.9645     
Epoch 9/10
1053/1053 [==============================] - 6s - loss: 0.4923 - acc: 0.9644     
Epoch 10/10
1053/1053 [==============================] - 6s - loss: 0.4475 - acc: 0.9648     
</pre>
</div>
</div>

<div class="output_area">
<div class="prompt output_prompt">Out[550]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&lt;keras.callbacks.History at 0x262226650&gt;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[551]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">model_visual</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">Y_train</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">64</span><span class="p">,</span><span class="n">verbose</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[551]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&lt;keras.callbacks.History at 0x2630d8cd0&gt;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For the first 10 epochs I trained the model in a verbose fashion to show you what's happening. After that, in the below cell you can see I turned off the verbosity to keep the code cleaner.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[552]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y_preds</span><span class="o">=</span><span class="n">model_visual</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[553]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">sum</span><span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="n">Y_preds</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[553]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>438.26369654744053</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Let's-look-at-some-of-our-predictions?">Let's look at some of our predictions?<a class="anchor-link" href="#Let's-look-at-some-of-our-predictions?">&#182;</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[554]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">f6</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;Genredict.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">Genre_ID_to_name</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f6</span><span class="p">)</span>
<span class="n">f6</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[555]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">sum</span><span class="p">(</span><span class="n">Y_preds</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[555]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>2.0173444656837738</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[556]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">sum</span><span class="p">(</span><span class="n">Y_preds</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[556]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>2.0</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[557]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">genre_list</span><span class="o">=</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[558]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">precs</span><span class="o">=</span><span class="p">[]</span>
<span class="n">recs</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">Y_preds</span><span class="p">)):</span>
    <span class="n">row</span><span class="o">=</span><span class="n">Y_preds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">gt_genres</span><span class="o">=</span><span class="n">Y_test</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">gt_genre_names</span><span class="o">=</span><span class="p">[]</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">gt_genres</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">==</span><span class="mi">1</span><span class="p">:</span>
            <span class="n">gt_genre_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">j</span><span class="p">]])</span>
    <span class="n">top_3</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">row</span><span class="p">)[</span><span class="o">-</span><span class="mi">3</span><span class="p">:]</span>
    <span class="n">predicted_genres</span><span class="o">=</span><span class="p">[]</span>
    <span class="k">for</span> <span class="n">genre</span> <span class="ow">in</span> <span class="n">top_3</span><span class="p">:</span>
        <span class="n">predicted_genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">genre</span><span class="p">]])</span>
    <span class="p">(</span><span class="n">precision</span><span class="p">,</span><span class="n">recall</span><span class="p">)</span><span class="o">=</span><span class="n">precision_recall</span><span class="p">(</span><span class="n">gt_genre_names</span><span class="p">,</span><span class="n">predicted_genres</span><span class="p">)</span>
    <span class="n">precs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">precision</span><span class="p">)</span>
    <span class="n">recs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">recall</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">50</span>==0:
        <span class="k">print</span> <span class="s2">&quot;Predicted: &quot;</span><span class="p">,</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">predicted_genres</span><span class="p">),</span><span class="s2">&quot; Actual: &quot;</span><span class="p">,</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gt_genre_names</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Predicted:  Adventure,Science Fiction,Action  Actual:  Adventure,Action,Comedy,Romance
Predicted:  Romance,Science Fiction,Adventure  Actual:  Drama
Predicted:  Adventure,Fantasy,Action  Actual:  Fantasy,Drama,Action,Western,Thriller
Predicted:  Documentary,Science Fiction,Action  Actual:  Drama,Action,Thriller,Science Fiction
Predicted:  Thriller,Action,Science Fiction  Actual:  Horror,Action,Thriller,Mystery
Predicted:  Comedy,Animation,Family  Actual:  Animation,Comedy,Family
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[559]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">precs</span><span class="p">)),</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">recs</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>0.489898989899 0.500220959596
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>So, even with just the poster i.e. visual features we are able to make great predictions! Sure, text outperforms the visual features, but the important thing is that it still work. In more complicated models, we can combine the two to make even better predictions. That is precisely what I work on in my research.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>These models were trained on CPU's, and a simple 1 layer model was used to show that there is a lot of information in this data that the models can extract. With a larger dataset, and more training I was able to bring these numbers to as high as 70%, which is the similar to textual features. Some teams in my class outperformed this even more. More data is the first thing you should try if you want better results. Then, you can start playing with training on GPUs, learning rate schedules and other hyperparameters. Finally, you can consider using ResNet, a much more powerful neural network model than VGG. All of these can be tried once you have a working knowledge of machine learning.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-8---Deep-Learning-to-get-Textual-Features">Section 8 - Deep Learning to get Textual Features<a class="anchor-link" href="#Section-8---Deep-Learning-to-get-Textual-Features">&#182;</a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Let's do the same thing as above with text now?</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>We will use an off the shelf representation for words - Word2Vec model. Just like VGGnet before, this is a model made available to get a meaningful representation. As the total number of words is small, we don't even need to forward propagate our sample through a network. Even that has been done for us, and the result is stored in the form of a dictionary. We can simply look up the word in the dictionary and get the Word2Vec features for the word.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>You can download the dictionary from here - <a href="https://drive.google.com/file/d/0B7XkCwpI5KDYNlNUTTlSS21pQmM/edit">https://drive.google.com/file/d/0B7XkCwpI5KDYNlNUTTlSS21pQmM/edit</a> <br>
Download it to the directory of this tutorial i.e. in the same folder as this ipython notebook.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[226]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">gensim</span> <span class="kn">import</span> <span class="n">models</span>
<span class="c1"># model2 = models.Word2Vec.load_word2vec_format(&#39;GoogleNews-vectors-negative300.bin&#39;, binary=True) </span>
<span class="n">model2</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">KeyedVectors</span><span class="o">.</span><span class="n">load_word2vec_format</span><span class="p">(</span><span class="s1">&#39;GoogleNews-vectors-negative300.bin&#39;</span><span class="p">,</span> <span class="n">binary</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Now, we can simply look up for a word in the above loaded model. For example, to get the Word2Vec representation of the word "King" we just do - model2['king']</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[227]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">model2</span><span class="p">[</span><span class="s1">&#39;king&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span>
<span class="k">print</span> <span class="n">model2</span><span class="p">[</span><span class="s1">&#39;dog&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>(300,)
(300,)
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>This way, we can represent the words in our overviews using this word2vec model. And then, we can use that as our X representations. So, instead of count of words, we are using a representation which is based on the semantic representation of the word. Mathematically, each word went from 3-4 dimensional (the length) to 300 dimensions!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For the same set of movies above, let's try and predict the genres from the deep representation of their overviews!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[228]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">final_movies_set</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[228]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>1265</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[231]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">nltk.tokenize</span> <span class="kn">import</span> <span class="n">RegexpTokenizer</span>
<span class="kn">from</span> <span class="nn">stop_words</span> <span class="kn">import</span> <span class="n">get_stop_words</span>
<span class="n">tokenizer</span> <span class="o">=</span> <span class="n">RegexpTokenizer</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\w+&#39;</span><span class="p">)</span>

<span class="c1"># create English stop words list</span>
<span class="n">en_stop</span> <span class="o">=</span> <span class="n">get_stop_words</span><span class="p">(</span><span class="s1">&#39;en&#39;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[232]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">movie_mean_wordvec</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">final_movies_set</span><span class="p">),</span><span class="mi">300</span><span class="p">))</span>
<span class="n">movie_mean_wordvec</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[232]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1265, 300)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Text needs some pre-processing before we can train the model. The only preprocessing we do here is - we delete commonly occurring words which we know are not informative about the genre. Think of it as the clutter in some sense. These words are often removed and are referred to as "stop words". You can look them up online. These include simple words like "a", "and", "but", "how", "or" and so on. They can be easily removed using the python package NLTK.</p>
<p>From the above dataset, movies with overviews which contain only stop words, or movies with overviews containing no words with word2vec representation are neglected. Others are used to build our Mean word2vec representation. Simply, put for every movie overview -</p>
<ul>
<li>Take movie overview</li>
<li>Throw out stop words</li>
<li>For non stop words:<ul>
<li>If in word2vec - take it's word2vec representation which is 300 dimensional</li>
<li>If not - throw word</li>
</ul>
</li>
<li>For each movie, calculate the arithmetic mean of the 300 dimensional vector representations for all words in the overview which weren't thrown out</li>
</ul>
<p>This mean becomes the 300 dimensional representation for the movie. For all movies, these are stored in a numpy array. So the X matrix becomes (1263,300). And, Y is (1263,20) i.e. binarized 20 genres, as before</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><strong>Why do we take the arithmetic mean?</strong>
If you feel that we should have kept all the words separately - Then you're thinking correct, but sadly we're limited by the way current day neural networks work. I will not mull over this for the fear of stressing too much on an otherwise irrelevant detail. But if you're interested, read this awesome paper - 
<a href="https://jiajunwu.com/papers/dmil_cvpr.pdf">https://jiajunwu.com/papers/dmil_cvpr.pdf</a></p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[241]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">genres</span><span class="o">=</span><span class="p">[]</span>
<span class="n">rows_to_delete</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">final_movies_set</span><span class="p">)):</span>
    <span class="n">mov</span><span class="o">=</span><span class="n">final_movies_set</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">movie_genres</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;genre_ids&#39;</span><span class="p">]</span>
    <span class="n">genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">movie_genres</span><span class="p">)</span>
    <span class="n">overview</span><span class="o">=</span><span class="n">mov</span><span class="p">[</span><span class="s1">&#39;overview&#39;</span><span class="p">]</span>
    <span class="n">tokens</span> <span class="o">=</span> <span class="n">tokenizer</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">overview</span><span class="p">)</span>
    <span class="n">stopped_tokens</span> <span class="o">=</span> <span class="p">[</span><span class="n">k</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">tokens</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">en_stop</span><span class="p">]</span>
    <span class="n">count_in_vocab</span><span class="o">=</span><span class="mi">0</span>
    <span class="n">s</span><span class="o">=</span><span class="mi">0</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">stopped_tokens</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">rows_to_delete</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
        <span class="n">genres</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="c1">#         print overview</span>
<span class="c1">#         print &quot;sample &quot;,i,&quot;had no nonstops&quot;</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">tok</span> <span class="ow">in</span> <span class="n">stopped_tokens</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">tok</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">model2</span><span class="o">.</span><span class="n">vocab</span><span class="p">:</span>
                <span class="n">count_in_vocab</span><span class="o">+=</span><span class="mi">1</span>
                <span class="n">s</span><span class="o">+=</span><span class="n">model2</span><span class="p">[</span><span class="n">tok</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span>
        <span class="k">if</span> <span class="n">count_in_vocab</span><span class="o">!=</span><span class="mi">0</span><span class="p">:</span>
            <span class="n">movie_mean_wordvec</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">s</span><span class="o">/</span><span class="nb">float</span><span class="p">(</span><span class="n">count_in_vocab</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">rows_to_delete</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
            <span class="n">genres</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="c1">#             print overview</span>
<span class="c1">#             print &quot;sample &quot;,i,&quot;had no word2vec&quot;</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[242]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="n">genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[242]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>1261</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[243]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">mask2</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">movie_mean_wordvec</span><span class="p">)):</span>
    <span class="k">if</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">rows_to_delete</span><span class="p">:</span>
        <span class="n">mask2</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">mask2</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[244]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">=</span><span class="n">movie_mean_wordvec</span><span class="p">[</span><span class="n">mask2</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[245]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[245]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1261, 300)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[246]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y</span><span class="o">=</span><span class="n">mlb</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">genres</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[247]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[247]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1261, 20)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[248]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">textual_features</span><span class="o">=</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">Y</span><span class="p">)</span>
<span class="n">f9</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;textual_features.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;wb&#39;</span><span class="p">)</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">textual_features</span><span class="p">,</span><span class="n">f9</span><span class="p">)</span>
<span class="n">f9</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[249]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># textual_features=(X,Y)</span>
<span class="n">f9</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;textual_features.pckl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">textual_features</span><span class="o">=</span><span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f9</span><span class="p">)</span>
<span class="n">f9</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[250]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="n">Y</span><span class="p">)</span><span class="o">=</span><span class="n">textual_features</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[251]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[251]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1261, 300)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[252]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y</span><span class="o">.</span><span class="n">shape</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[252]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>(1261, 20)</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[253]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">mask_text</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">X</span><span class="p">))</span><span class="o">&lt;</span><span class="mf">0.8</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[254]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">X_train</span><span class="o">=</span><span class="n">X</span><span class="p">[</span><span class="n">mask_text</span><span class="p">]</span>
<span class="n">Y_train</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="n">mask_text</span><span class="p">]</span>
<span class="n">X_test</span><span class="o">=</span><span class="n">X</span><span class="p">[</span><span class="o">~</span><span class="n">mask_text</span><span class="p">]</span>
<span class="n">Y_test</span><span class="o">=</span><span class="n">Y</span><span class="p">[</span><span class="o">~</span><span class="n">mask_text</span><span class="p">]</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Once again, we use a very similar, super simple architecture as before.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[258]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">keras.models</span> <span class="kn">import</span> <span class="n">Sequential</span>
<span class="kn">from</span> <span class="nn">keras.layers</span> <span class="kn">import</span> <span class="n">Dense</span><span class="p">,</span> <span class="n">Activation</span>

<span class="n">model_textual</span> <span class="o">=</span> <span class="n">Sequential</span><span class="p">([</span>
    <span class="n">Dense</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="n">input_shape</span><span class="o">=</span><span class="p">(</span><span class="mi">300</span><span class="p">,)),</span>
    <span class="n">Activation</span><span class="p">(</span><span class="s1">&#39;relu&#39;</span><span class="p">),</span>
    <span class="n">Dense</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span>
    <span class="n">Activation</span><span class="p">(</span><span class="s1">&#39;softmax&#39;</span><span class="p">),</span>
<span class="p">])</span>

<span class="n">model_textual</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">optimizer</span><span class="o">=</span><span class="s1">&#39;rmsprop&#39;</span><span class="p">,</span>
              <span class="n">loss</span><span class="o">=</span><span class="s1">&#39;binary_crossentropy&#39;</span><span class="p">,</span>
              <span class="n">metrics</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;accuracy&#39;</span><span class="p">])</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[259]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">model_textual</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">Y_train</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Epoch 1/10
982/982 [==============================] - 0s - loss: 0.4819 - acc: 0.8520     
Epoch 2/10
982/982 [==============================] - 0s - loss: 0.4642 - acc: 0.8520     
Epoch 3/10
982/982 [==============================] - 0s - loss: 0.4527 - acc: 0.8520     
Epoch 4/10
982/982 [==============================] - 0s - loss: 0.4456 - acc: 0.8520     
Epoch 5/10
982/982 [==============================] - 0s - loss: 0.4407 - acc: 0.8520     
Epoch 6/10
982/982 [==============================] - 0s - loss: 0.4367 - acc: 0.8520     
Epoch 7/10
982/982 [==============================] - 0s - loss: 0.4332 - acc: 0.8520     
Epoch 8/10
982/982 [==============================] - 0s - loss: 0.4295 - acc: 0.8520     
Epoch 9/10
982/982 [==============================] - 0s - loss: 0.4260 - acc: 0.8520     
Epoch 10/10
982/982 [==============================] - 0s - loss: 0.4227 - acc: 0.8520     
</pre>
</div>
</div>

<div class="output_area">
<div class="prompt output_prompt">Out[259]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&lt;keras.callbacks.History at 0x4e27e3850&gt;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[260]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">model_textual</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">Y_train</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">500</span><span class="p">,</span><span class="n">verbose</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt output_prompt">Out[260]:</div>



<div class="output_text output_subarea output_execute_result">
<pre>&lt;keras.callbacks.History at 0x4e27e3a10&gt;</pre>
</div>

</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[261]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">score</span> <span class="o">=</span> <span class="n">model_textual</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span> <span class="n">Y_test</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">249</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>249/279 [=========================&gt;....] - ETA: 0s</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[262]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%.2f%%</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">model_textual</span><span class="o">.</span><span class="n">metrics_names</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">score</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">*</span><span class="mi">100</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>acc: 86.52%
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[263]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">Y_preds</span><span class="o">=</span><span class="n">model_textual</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[264]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">genre_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">10769</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[266]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="s2">&quot;Our predictions for the movies are - </span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="n">precs</span><span class="o">=</span><span class="p">[]</span>
<span class="n">recs</span><span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">Y_preds</span><span class="p">)):</span>
    <span class="n">row</span><span class="o">=</span><span class="n">Y_preds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">gt_genres</span><span class="o">=</span><span class="n">Y_test</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">gt_genre_names</span><span class="o">=</span><span class="p">[]</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">gt_genres</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">==</span><span class="mi">1</span><span class="p">:</span>
            <span class="n">gt_genre_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">j</span><span class="p">]])</span>
    <span class="n">top_3</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">row</span><span class="p">)[</span><span class="o">-</span><span class="mi">3</span><span class="p">:]</span>
    <span class="n">predicted_genres</span><span class="o">=</span><span class="p">[]</span>
    <span class="k">for</span> <span class="n">genre</span> <span class="ow">in</span> <span class="n">top_3</span><span class="p">:</span>
        <span class="n">predicted_genres</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Genre_ID_to_name</span><span class="p">[</span><span class="n">genre_list</span><span class="p">[</span><span class="n">genre</span><span class="p">]])</span>
    <span class="p">(</span><span class="n">precision</span><span class="p">,</span><span class="n">recall</span><span class="p">)</span><span class="o">=</span><span class="n">precision_recall</span><span class="p">(</span><span class="n">gt_genre_names</span><span class="p">,</span><span class="n">predicted_genres</span><span class="p">)</span>
    <span class="n">precs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">precision</span><span class="p">)</span>
    <span class="n">recs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">recall</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">i</span><span class="o">%</span><span class="k">50</span>==0:
        <span class="k">print</span> <span class="s2">&quot;Predicted: &quot;</span><span class="p">,</span><span class="n">predicted_genres</span><span class="p">,</span><span class="s2">&quot; Actual: &quot;</span><span class="p">,</span><span class="n">gt_genre_names</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>Our predictions for the movies are - 

Predicted:  [u&#39;Science Fiction&#39;, u&#39;Action&#39;, u&#39;Adventure&#39;]  Actual:  [u&#39;Adventure&#39;, u&#39;Action&#39;, u&#39;Comedy&#39;, u&#39;Romance&#39;]
Predicted:  [u&#39;Thriller&#39;, u&#39;Crime&#39;, u&#39;Mystery&#39;]  Actual:  [u&#39;Drama&#39;, u&#39;Thriller&#39;, u&#39;Science Fiction&#39;]
Predicted:  [u&#39;Action&#39;, u&#39;Crime&#39;, u&#39;Thriller&#39;]  Actual:  [u&#39;Adventure&#39;, u&#39;Action&#39;, u&#39;Comedy&#39;, u&#39;Thriller&#39;, u&#39;Crime&#39;]
Predicted:  [u&#39;Family&#39;, u&#39;Horror&#39;, u&#39;Comedy&#39;]  Actual:  [u&#39;Horror&#39;, u&#39;Action&#39;, u&#39;Thriller&#39;]
Predicted:  [u&#39;Crime&#39;, u&#39;Thriller&#39;, u&#39;Drama&#39;]  Actual:  [u&#39;Action&#39;, u&#39;Science Fiction&#39;]
Predicted:  [u&#39;Drama&#39;, u&#39;Thriller&#39;, u&#39;Mystery&#39;]  Actual:  [u&#39;Drama&#39;, u&#39;Thriller&#39;, u&#39;Mystery&#39;, u&#39;Romance&#39;]
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[267]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">precs</span><span class="p">)),</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">recs</span><span class="p">))</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">
<div class="prompt"></div>

<div class="output_subarea output_stream output_stdout output_text">
<pre>0.519713261649 0.563918757467
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Even without much tuning of the above model, these results are able to beat our previous results.</p>
<p>Note - I got accuracies as high as 78% when doing classification using plots scraped from Wikipedia. The large amount of information was very suitable for movie genre classification with a deep model. Strongly suggest you to try playing around with architectures.</p>

</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Section-9---Upcoming-Tutorials-and-Acknowledgements">Section 9 - Upcoming Tutorials and Acknowledgements<a class="anchor-link" href="#Section-9---Upcoming-Tutorials-and-Acknowledgements">&#182;</a></h1><p>Congrats! This is the end of our pilot project! Needless to say, a lot of the above content may be new to you, or may be things that you know very well. If it's the former, I hope this tutorial would have helped you. If it is the latter and you think I wrote something incorrect or that my understanding can be improved, feel free to create a github issue so that I can correct it!</p>
<p>Writing tutorials can take a lot of time, but it is a great learning experience. I am currently working on a tutorial focussing on word embeddings, which will explore word2vec and other word embeddings in detail. While it will take some time to be up, I will post a link to it's repository on the README for this project so that interested readers can find it.</p>
<p>I would like to thank a few of my friends who had an indispensible role to play in me making this tutorial. Firstly, Professor Hanspeter Pfister and Verena Kaynig at Harvard, who helped guide this tutorial/project and scope it. Secondly, my friends Sahil Loomba and Matthew Tancik for their suggestions and editing the material and the presentation of the storyline. Thirdly, Zoya Bylinskii at MIT for constantly motivating me to put in my effort into this tutorial. Finally, all others who helped me feel confident enough to take up this task and to see it till the end. Thanks all of you!</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
    </div>
  </div>
</body>

 


</html>
